XAML:绑定DataTemplate中的属性

Dow*_*wse 8 xaml binding properties datatemplate

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

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

我这个例子我试图将a的Visibility属性绑定到我的viewmodel CheckBox中的DataTemplate一个Property.(纯粹用于学习/演示,使用此场景.)

我有一个简单的DataModel命名Item,但在这个例子中没什么关系.

class Item : INotifyPropertyChanged
{

    // Fields...
    private bool _IsRequired;
    private string _ItemName;
Run Code Online (Sandbox Code Playgroud)

还有一个名为ItemViewModel的相当简单的View Model.

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"));
        }
Run Code Online (Sandbox Code Playgroud)

(INotifyPropertyChanged为简洁起见,省略了构造函数和实现.)

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

<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>
Run Code Online (Sandbox Code Playgroud)

"隐藏复选框"复选框已绑定IsCheckBoxChecked并用于更新IsCheckBoxVisible.我还在下面添加了一些额外的控件DataTemplate来证明(对我自己)一切正常.)

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

当我运行应用程序,检查并取消选中"隐藏复选框"时,DataTemplate按预期控制函数外部,但是,唉,Checkbox数据模板内部保持不变.

我成功了:

IsVisible="{Binding IsChecked, Converter={StaticResource VisibilityConverter}, ElementName=checkBox}"
Run Code Online (Sandbox Code Playgroud)

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

我真的很感谢您提供的任何帮助或建议.

谢谢.

Dun*_*son 20

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

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

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

<Window [...blah blah...]
        x:Name="MyWindow">
Run Code Online (Sandbox Code Playgroud)

将绑定更改为如下所示:

<CheckBox Grid.Column="1"
          Visibility="{Binding DataContext.IsCheckBoxVisible, ElementName=MyWindow, Converter={StaticResource VisibilityConverter}}">
Run Code Online (Sandbox Code Playgroud)

我们使用Window作为Binding的源代码,然后查看其DataContext属性(应该是您的属性ItemViewModel,然后删除IsCheckBoxVisible属性).

如果你想要更好的东西,另一种选择是使用代理对象来引用你的DataContext.请参阅有关DataContextProxy的这篇文章.