XAML:绑定DataTemplate中的属性

时间:2013-04-01 17:48:07

标签: xaml binding properties datatemplate

我对XAML很新,但很乐意学习它。我真正挣扎的是将属性绑定到DataTemplate中的元素。

我创建了一个简单的WPF示例,(希望)解释了我的问题。

我在这个示例中尝试将VisibilityCheckBox的{​​{1}}属性绑定到我的viewmodel中的属性。 (仅将此场景用于学习/演示。)

我有一个名为DataTemplate的简单DataModel,但在此示例中没什么关系。

Item

一个名为ItemViewModel的相当简单的视图模型。

class Item : INotifyPropertyChanged
{

    // Fields...
    private bool _IsRequired;
    private string _ItemName;

(为简洁起见,省略了构造函数和class ItemViewModel : INotifyPropertyChanged { private ObservableCollection<Item> _Items; private bool _IsCheckBoxChecked; private bool _IsCheckBoxVisible; public ObservableCollection<Item> Items { get { return _Items; } set { _Items = value; } } public bool IsCheckBoxChecked { get { return _IsCheckBoxChecked; } set { if (_IsCheckBoxChecked == value) return; _IsCheckBoxChecked = value; if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs("IsCheckBoxChecked")); PropertyChanged(this, new PropertyChangedEventArgs("IsCheckBoxVisible")); } } } public bool IsCheckBoxVisible { get { return !_IsCheckBoxChecked; } set { if (_IsCheckBoxVisible == value) return; _IsCheckBoxVisible = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("IsCheckBoxVisible")); } 实现。)

MainPage.xaml中的控件如下所示。

INotifyPropertyChanged

隐藏CheckBoxes&#39;复选框绑定到<Window.Resources> <local:VisibilityConverter x:Key="VisibilityConverter"/> </Window.Resources> <Window.DataContext> <local:ItemViewModel/> </Window.DataContext> <Grid> <StackPanel> <CheckBox x:Name="checkBox" Content="Hide CheckBoxes" FontSize="14" IsChecked="{Binding IsCheckBoxChecked, Mode=TwoWay}" /> <ListView ItemsSource="{Binding Items}" HorizontalContentAlignment="Stretch" > <ListView.ItemTemplate > <DataTemplate> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <TextBlock Text="{Binding ItemName}"/> <CheckBox Grid.Column="1" Visibility="{Binding IsCheckBoxVisible, Converter={StaticResource VisibilityConverter}}" > <CheckBox.DataContext> <local:ItemViewModel/> </CheckBox.DataContext> </CheckBox> </Grid> </DataTemplate> </ListView.ItemTemplate> </ListView> <StackPanel Orientation="Horizontal" Margin="4,4,0,0"> <TextBlock Text="IsCheckBoxVisible:"/> <TextBlock Text="{Binding IsCheckBoxVisible}" Margin="4,0,0,0" FontWeight="Bold" /> </StackPanel > <Button Content="Button" Visibility="{Binding IsCheckBoxVisible, Converter={StaticResource VisibilityConverter}}" Margin="4,4,4,4"/> </StackPanel> </Grid> ,用于更新IsCheckBoxChecked。我还在IsCheckBoxVisible下面添加了一些额外的控件来证明(对我自己)一切正常。)

我还实施了Jeff Wilcox的价值转换器。 (谢谢。)http://www.jeff.wilcox.name/2008/07/visibility-type-converter/

当我运行应用时,检查并取消选中“隐藏复选框”,按预期在DataTemplate功能外控制,但是,唉,数据模板内的DataTemplate保持不变

我取得了成功:

Checkbox

但我不只是尝试模仿另一个控件,而是根据一个值做出决定。

我真的非常感谢您提供的任何帮助或建议。

谢谢。

1 个答案:

答案 0 :(得分:19)

当您在DataTemplate中时,您的DataContext是数据模板化对象,在本例中为Item。因此,DataTemplate中CheckBox的DataContext是Item,而不是ItemViewModel。你可以通过<TextBlock Text="{Binding ItemName}"/>看到这个,它绑定到Item类的属性。绑定到IsCheckBoxVisible正试图在Item上找到一个名为IsCheckBoxVisible的属性。

有很多方法可以解决这个问题,但到目前为止最简单的方法是:

在你的窗口(在xaml中),给它和x:名字。例如:

<Window [...blah blah...]
        x:Name="MyWindow">

将绑定更改为:

<CheckBox Grid.Column="1"
          Visibility="{Binding DataContext.IsCheckBoxVisible, ElementName=MyWindow, Converter={StaticResource VisibilityConverter}}">

我们使用Window作为Binding的源,然后查看其DataContext属性(应该是您的ItemViewModel,然后关闭IsCheckBoxVisible属性。

如果你想要更好的东西,另一种选择是使用代理对象来引用你的DataContext。请参阅this article on DataContextProxy