绑定到DataTemplate中的viewmodel属性 [英] Binding to a viewmodel property in a DataTemplate

查看:67
本文介绍了绑定到DataTemplate中的viewmodel属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对XAML相当陌生,但喜欢学习它.我真正挣扎的是将属性绑定到DataTemplate中的元素.

I'm fairly new to XAML but enjoying learning it. The thing I'm really struggling with is binding a property to an element in a DataTemplate.

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

I have created a simple WPF example to, (hopefully,) explain my problem.

在这个示例中,我试图将DataTemplateCheckBoxVisibility属性绑定到我的视图模型中的Property. (仅将这种情况用于学习/演示.)

I this example I am trying to bind the Visibility property of a CheckBox in a DataTemplate to a Property in my viewmodel. (Using this scenario purely for learning/demo.)

我有一个名为Item的简单数据模型,但在此示例中没有什么意义.

I have a simple DataModel named Item, but is of little relevance in this example.

class Item : INotifyPropertyChanged
{

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

还有一个相当简单的名为ItemViewModel的视图模型.

And a fairly simple View Model named 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实现.)

(Constructors and INotifyPropertyChanged implementation omitted for brevity.)

在MainPage.xaml中布置的控件如下.

Controls laid out in MainPage.xaml as follows.

<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下面添加了一些额外的控件,以(对我自己)证明一切正常.)

The 'Hide CheckBoxes' checkbox is bound to IsCheckBoxChecked and is used to update IsCheckBoxVisible. I've also added a couple of extra controls below the DataTemplate to prove, (to myself,) the everything works.)

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

I have also implemented Jeff Wilcox's value converter. (Thank you.) http://www.jeff.wilcox.name/2008/07/visibility-type-converter/

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

When I run the app, checking and unchecking the 'Hide Checkbox', controls outside the DataTemplate function as expected but, alas, the Checkbox inside the data template remains unchanged.

我在以下方面取得了成功:

I have had success with:

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

但是我不仅在尝试模仿另一个控件,还基于值进行决策.

But I'm not just trying mimic another control but make decisions based on a value.

我非常感谢您可以提供的任何帮助或建议.

I would REALLY appreciate any help or advice you can offer.

谢谢.

推荐答案

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

When you are in a DataTemplate, your DataContext is the data templated object, in this case an Item. Thus, the DataContext of the CheckBox in the DataTemplate is an Item, not your ItemViewModel. You can see this by your <TextBlock Text="{Binding ItemName}"/>, which binds to a property on the Item class. The Binding to IsCheckBoxVisible is trying to find a property called IsCheckBoxVisible on Item.

有两种解决方法,但是到目前为止,最简单的方法是:

There are a couple of ways around this, but by far the easiest is to do this:

在您的Window(在xaml中)上,输入x和Name.例如:

On your Window (in the xaml), give it and x:Name. Eg:

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

将绑定更改为以下形式:

Change your binding to look like this:

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

我们将Window用作绑定的源,然后查看其DataContext属性(应为您的ItemViewModel,然后提取IsCheckBoxVisible属性.

We're using the Window as the source for the Binding, then looking at its DataContext property (which should be your ItemViewModel, and then pulling off the IsCheckBoxVisible property.

如果需要更高级的选择,另一个选择是使用代理对象来引用您的DataContext.请参阅

Another option, if you want something fancier, is to use a proxy object to reference your DataContext. See this article on DataContextProxy.

这篇关于绑定到DataTemplate中的viewmodel属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆