XAML:在一个DataTemplate绑定属性(XAML: Binding a property

2019-08-18 17:00发布

我是相当新的XAML而是享受学习它。 事情我真的是在一个属性绑定到一个元素挣扎DataTemplate

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

我这个例子中,我试图将绑定Visibility一个财产CheckBoxDataTemplate在我的视图模型一个属性。 (纯粹使用此方案进行学习/演示。)

我有一个名为一个简单的DataModel Item ,但很少在这个例子中的相关性。

class Item : INotifyPropertyChanged
{

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

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

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

(构造器和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>

在“隐藏复选框”复选框被绑定到IsCheckBoxChecked和用于更新IsCheckBoxVisible 。 我还添加了一对额外的控制下面DataTemplate证明,(对自己)的一切工作。)

我还实施杰夫·威尔考克斯的价值转换。 (谢谢。) http://www.jeff.wilcox.name/2008/07/visibility-type-converter/

当我运行应用程序,检查和取消选中“隐藏复选框”,控制以外DataTemplate功能如预期,但是,唉,该Checkbox中的数据模板内保持不变。

我已经成功使用:

IsVisible="{Binding IsChecked, Converter={StaticResource VisibilityConverter}, ElementName=checkBox}"

但我不只是试图模仿另一个控制,但要根据价值决定。

我真的很感激任何帮助或建议,您可以提供。

谢谢。

Answer 1:

当你在一个DataTemplate,你的DataContext是数据模板对象,在这种情况下一个Item 。 因此,在DataTemplate中CheckBox的DataContext的是一个Item ,而不是你ItemViewModel 。 你可以通过你看到这个<TextBlock Text="{Binding ItemName}"/>结合对属性Item类。 绑定到IsCheckBoxVisible正试图找到一个名为IsCheckBoxVisible物业Item

有一对夫妇的解决这个办法,但截至目前为止最简单的就是要做到这一点:

你的窗口(在XAML),给它和X:名称。 例如:

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

更改绑定到这个样子:

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

我们使用窗口作为源绑定,然后看着它的DataContext属性(这应该是你的ItemViewModel ,然后脱下IsCheckBoxVisible财产。

另一种选择,如果你想要的东西票友,是使用代理对象引用您的DataContext。 请参阅这篇文章DataContextProxy 。



文章来源: XAML: Binding a property in a DataTemplate