[英]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。 然后将为您在列表框中选择的任何人获取该系列的鞋子。 这将是一种相当笨重的绑定,并且将两者绑定到视图模型中的属性通常更清晰。
如果您将该列表框绑定到集合视图,您也可以在绑定中使用当前项目/符号。
当然,这只会给你类型名称,因为它不知道如何展示鞋子。 但这没有问题,因为 wpf 有一个完整的数据模板系统。 这允许你给它一个用于鞋子的模板。
你应该能够在谷歌上搜索所有这些东西的例子,但这里有一个专门在 tabcontrol 上的例子:
如何将 TabControl 绑定到 ViewModel 集合?
我希望这足以为您指明正确的方向。 或者至少沿着岩石较少的路径。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.