繁体   English   中英

C# wpf 基于listitem选择绑定tabcontrol

[英]C# wpf bind tabcontrol based on listitem selection

我想根据 ListItem 选择更改完整的 TabControl。 因此,我在循环中生成一个带有键(列表项)和值(TabControl)的字典。 每个 TabControl 包含 10 个 TabItem。

主窗口.xaml.cs

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));
        }
    }
}

我试图将堆栈面板绑定到 tabcontrols,但我无法让它工作。

这是MainWindow.xaml代码。

<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>

所以,基本上,我想实现一个主/细节视图,其中主是列表框,细节是它的所属 TabControl。

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

您需要一个 ListBox 和一个 TabControl。

您拥有的两个控件都有项目控件。

它们都继承自 Selector,因此它们具有 SelectedItem。

将一组视图模型绑定到您的列表框,将它们称为有意义的东西。 PersonViewModel 或 FruitViewModel 什么的。 不要将它们称为 listboxitem 或任何与 UI 控件名称相同或类似的名称。 每行一个。 但是让我们将它们称为 RowVM,就像在保存列表框行数据的视图模型中一样。

如果您绑定到该 ListBox 的 SelectedItem,您将获得一个 RowVM 实例。

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

不过,让我们回到有意义的名字。

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

您可以将该选项卡控件的 itemssource 绑定到列表框所选项目的 Shoes。 然后将为您在列表框中选择的任何人获取该系列的鞋子。 这将是一种相当笨重的绑定,并且将两者绑定到视图模型中的属性通常更清晰。

如果您将该列表框绑定到集合视图,您也可以在绑定中使用当前项目/符号。

https://social.technet.microsoft.com/wiki/contents/articles/29859.wpf-tips-bind-to-current-item-of-collection.aspx

当然,这只会给你类型名称,因为它不知道如何展示鞋子。 但这没有问题,因为 wpf 有一个完整的数据模板系统。 这允许你给它一个用于鞋子的模板。

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

如何将 TabControl 绑定到 ViewModel 集合?

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM