XAML:在一个DataTemplate绑定属性 [英] XAML: Binding a property in a DataTemplate
问题描述
我是相当新的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.
我这个例子,我想在一个DataTemplate复选框的可见性属性绑定到我的视图模型中的财产。 (纯粹使用此方案学习/演示。)
I this example I am trying to bind the Visibility property of a checkbox in a datatemplate to a Property in my view model. (Using this scenario purely for learning/demo.)
我有一个名为'项目'简单的DataModel,但无关紧要在这个例子中。
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.)
我也实施了杰夫·威尔考克斯的价值转换器。 (谢谢) http://www.jeff.wilcox.name / 2008/07 /可视性型转换器/
I have also implemented Jeff Wilcox's value converter. (Thank you.) http://www.jeff.wilcox.name/2008/07/visibility-type-converter/
当我运行应用程序,检查和取消选中隐藏复选框,控制的DataTemplate功能外如预期,但是,唉,该数据模板内保持不变。
When I run the app, checking and unchecking the 'Hide Checkbox', controls outside the DataTemplate function as expected but, alas, the inside the data template remains unchanged.
我曾与成功:
IsVisible="{Binding IsChecked, Converter={StaticResource VisibilityConverter}, ElementName=checkBox}"
但我不会只是试图模仿另一个控制,但基于价值作出决策。
But I'm not just trying mimic another control but make decisions based on a value.
我真的AP preciate任何帮助或建议,您可以提供。
I would REALLY appreciate any help or advice you can offer.
感谢您。
推荐答案
当你在一个DataTemplate,你的DataContext是模板对象中的数据,在这种情况下,项目
。因此,在DataTemplate中CheckBox的DataContext的是项目
,不是你的 ItemViewModel
。 TextBlock的文本={结合ITEMNAME}/&GT;你可以通过你的&LT看到这个
,它结合到一个属性上的项目
类。绑定到IsCheckBoxVisible正试图找到一个名为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:
在你的窗口(在XAML),给它和X:名称。例如:
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}}">
我们正在使用的窗口作为源绑定,然后看着它的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。见<一href=\"http://weblogs.asp.net/dwahlin/archive/2009/08/20/creating-a-silverlight-datacontext-proxy-to-simplify-data-binding-in-nested-controls.aspx\">this文章DataContextProxy 。
Another option, if you want something fancier, is to use a proxy object to reference your DataContext. See this article on DataContextProxy.
这篇关于XAML:在一个DataTemplate绑定属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!