C# 基于listitem选择的C wpf绑定选项卡控件

C# 基于listitem选择的C wpf绑定选项卡控件,c#,wpf,data-binding,C#,Wpf,Data Binding,我想根据ListItem选择更改一个完整的TabControl。因此,我生成了一个循环中包含Keylist项和ValueTabControl的字典。每个TabControl包含10个TabItems MainWindow.xaml.cs 我试图将stackpanel绑定到tabcontrols,但无法使其工作 这是MainWindow.xaml代码 所以,基本上,我想实现一个主/详细视图,其中主视图是listbox,详细视图是它的下一个选项卡控件 我知道,我可以根据列表项选择手动添加/删除Sta

我想根据ListItem选择更改一个完整的TabControl。因此,我生成了一个循环中包含Keylist项和ValueTabControl的字典。每个TabControl包含10个TabItems

MainWindow.xaml.cs

我试图将stackpanel绑定到tabcontrols,但无法使其工作

这是MainWindow.xaml代码

所以,基本上,我想实现一个主/详细视图,其中主视图是listbox,详细视图是它的下一个选项卡控件


我知道,我可以根据列表项选择手动添加/删除Stackpanel的子项,但在我看来,这似乎不是MVVM的方式。

您需要一个ListBox和一个TabControl

您拥有的两个控件都是ItemsControl

它们都是从选择器继承的,因此它们都有SelectedItem

将viewmodels集合绑定到listbox,称之为有意义的东西。PersonViewModel或水果视图Model之类的。不要称它们为listboxitem或任何与UI控件同名或类似的名称。每排一个。但是,让我们将它们称为RowVM,就像在保存列表框行数据的viewmodel中一样

如果绑定到该列表框的SelectedItem,则会得到一个RowVM实例

您可以将它从列表框绑定到WindowViewModel中的属性。您还可以从其他控件绑定到该属性

让我们回到有意义的名字

也许一个人有鞋子。您将在该选项卡控件中显示的鞋子集合。在列表框中选择一个人,您将在选项卡控件中看到他的鞋子。所以PersonViewModel会有一个可观察到的鞋子集合

您可以将该tabcontrol的itemssource绑定到listbox中选定项的Shoes。然后,它将为列表框中您选择的任何人抓取该鞋集。 不过,这将是一种相当笨拙的绑定,而且将两者绑定到viewmodel中的属性通常更干净

如果将该列表框绑定到collectionview,也可以在绑定中使用当前项/符号

当然,这只会给出类型名称,因为它不知道如何显示鞋。 但这并没有问题,因为wpf有一个完整的数据模板系统。这让你可以给它一个模板来制作鞋子

你应该能够在谷歌上搜索所有这些东西的例子,但这里有一个关于tabcontrol的例子:


我希望这足以为你指明正确的方向。或者至少沿着岩石较少的路径。

您拥有的不是mvvm,您应该绑定viewmodels的集合,而不是控件。然后,应该将它们模板化到UI中。没有listbox容器之类的东西。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        ListboxContainer listBoxContainer = new ListboxContainer();
        TabControlContainer tabControlContainer = new TabControlContainer();

        Dictionary<string, TabControl> tabControlDict = new Dictionary<string, TabControl>();

        public MainWindow()
        {
            InitializeComponent();

            listBoxContainer.ListBoxItems = new string[] { "TabControl1", "TabControl2", "TabControl3" };

            DataContext = listBoxContainer;

            // Generate tabcontrols per listbox item
            foreach (var key in listBoxContainer.ListBoxItems)
            {
                TabControl tabControl = new TabControl();
                TabItem tabItem = new TabItem();

                for (int i = 0; i < 10; i++)
                {
                    tabItem.Header = $"Header: {i}";
                }

                tabControl.Items.Add(tabItem);

                tabControlDict.Add(key, tabControl);
            }

            tabControlContainer.TabControls = tabControlDict.Values.ToArray();


        }

    }

    public class TabControlContainer : INotifyPropertyChanged
    {
        private TabControl[] _tabControls;

        public TabControl[] TabControls
        {
            get => _tabControls;
            set
            {
                if (value != _tabControls)
                {
                    _tabControls = value;
                    NotifyPropertyChanged("TabControls");
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public class ListboxContainer : INotifyPropertyChanged
    {
        private string[] _listBoxitems;

        public string[] ListBoxItems
        {
            get => _listBoxitems;
            set
            {
                if (value != _listBoxitems)
                {
                    _listBoxitems = value;
                    NotifyPropertyChanged("ListBoxItems");
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <DockPanel>
        <ListBox x:Name="Listbox" ItemsSource="{Binding ListBoxItems}"/>
        <StackPanel x:Name="TabControlContainer">
            <ItemsControl ItemsSource="{Binding TabControls}">
                <!--<ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>-->
            </ItemsControl>
        </StackPanel>
    </DockPanel>
</Window>