我从WPF开始,试图了解如何正确设置MVVM。目前,我有一个具有ListBox的UserControl。列表框包含一个复选框列表,当选中该复选框时,我要显示一个TabItem,其中包含与该复选框关联的用户控件。首先,我找到了一种创建CheckListBox here的方法,但是现在当我尝试创建标签页时,我得到了与TabControls ItemsSource相关的绑定异常:
System.Windows.Data Error: 40 : BindingExpression path error: 'Items' property not found on 'object' ''DataTemplate' (HashCode=22018304)'. BindingExpression:Path=Items.CheckedItems; DataItem='DataTemplate' (HashCode=22018304); target element is 'TabControl' (Name='tc_TabItems'); target property is 'ItemsSource' (type 'IEnumerable')
System.Windows.Data Error: 40 : BindingExpression path error: 'selectedItem' property not found on 'object' ''DataTemplate' (HashCode=22018304)'. BindingExpression:Path=selectedItem; DataItem='DataTemplate' (HashCode=22018304); target element is 'TabControl' (Name='tc_TabItems'); target property is 'SelectedItem' (type 'Object')
我的MainWindow.xaml:
<Window x:Class="CheckListBox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CheckListBox"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<DataTemplate DataType="{x:Type local:TabItemViewModel}">
<local:TabItemUserControl />
</DataTemplate>
<DataTemplate x:Key="TabHeader" DataType="{x:Type local:TabItemViewModel}">
<TextBlock Text="{Binding Value.Name}"/>
</DataTemplate>
</Window.Resources>
<Grid Background="#FFE5E5E5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ListBox ItemsSource="{Binding Items}" SelectedItem="{Binding selectedItem}" Margin="4" SelectionMode="Extended" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Name="check" IsChecked="{Binding IsChecked, Mode=TwoWay}" Margin="3" VerticalAlignment="Center" />
<ContentPresenter Content="{Binding Value.Name}" Margin="1"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<StackPanel Grid.Column="1" >
<TextBlock FontWeight="Bold" >Selected Items</TextBlock>
<ItemsControl Grid.Column="1" Margin="4" x:Name="items" ItemsSource="{Binding Path=Items.SelectedItems}" DisplayMemberPath="Value.Name" />
</StackPanel>
<TabControl Name="tc_TabItems" Grid.Column="2" TabStripPlacement="Right"
ItemsSource="{Binding Items.SelectedItems}"
SelectedItem="{Binding selectedItem}"
>
<TabControl.ItemTemplate>
<DataTemplate DataType="{x:Type local:TabItemViewModel}">
<TextBlock Text="{Binding Value.Name}"/>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.DataContext>
<DataTemplate>
<TabItem Content="{Binding Value}"></TabItem>
</DataTemplate>
</TabControl.DataContext>
</TabControl>
</Grid>
如果删除TabControl.DataContext
,则绑定错误消失,并出现带有适当标题的TabItem,但显然DataContext为空。
MainWindow.xaml.cs:
...
public MainWindow () {
InitializeComponent();
this.DataContext = new ViewModel();
}
ViewModel:
private TabItemViewModel _selectedItem;
private CheckableObservableCollection<TabItemViewModel> _items;
public CheckableObservableCollection<TabItemViewModel> Items { get { return _items; } set { SetField( ref _items, value ); } }
public TabItemViewModel selectedItem { get { return _selectedItem; } set {SetField(ref _selectedItem, value); }}
public ViewModel () {
//Items = new CheckableObservableCollection<TabItemUserControl> { "this", "is", "a", "test" };
Items = new CheckableObservableCollection<TabItemViewModel>();
Items.Add( new TabItemViewModel { Name = "Name", Temp = "Temp1" } );
Items.Add( new TabItemViewModel { Name = "Nameington", Temp = "Temp2" } );
Items.Add( new TabItemViewModel { Name = "NameNameington", Temp = "Temp3" } );
*我省略了CheckableObservableCollection和CheckWrapper,因为它们与链接中的大多数相同。我觉得TabItemViewModel并不是真正必需的,因为它是一组属性,可以在ViewModel示例中设置和使用
为澄清上述错误,只有在出现TabControl.DataContext
时才会发生(如果我删除该部分,则输出中不会出现错误)。
答案 0 :(得分:0)
该错误告诉您问题所在:
在“对象”“ DataTemplate”上找不到“ Items”属性 (HashCode = 22018304)'
您将TabControl.DataContext设置为DataTemplate。 DataTemplate没有Items属性,因此会出现错误。
您似乎希望ViewModel成为DataContext。因此,只需不在TabControl上设置DataContext,它就会继承其父级的DataContext。它将一直冒泡直到到达窗口,该窗口具有您在代码中设置的DataContext,即新的ViewModel()。