wpf 将属性绑定到 DataTemplateSelector
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22011005/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bind a property to DataTemplateSelector
提问by eka808
I want to design a DataTemplateSelector who compare the given value with a one passed in parameter and choose the right template if the value is superior or inferior
我想设计一个 DataTemplateSelector 将给定的值与传入的参数进行比较,并在值优劣时选择正确的模板
I came with the following :
我带来了以下内容:
class InferiorSuperiorTemplateSelector : DataTemplateSelector
{
public DataTemplate SuperiorTemplate { get; set; }
public DataTemplate InferiorTemplate { get; set; }
public double ValueToCompare { get; set; }
public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
{
double dpoint = Convert.ToDouble(item);
return (dpoint >= ValueToCompare || dpoint == null) ? SuperiorTemplate : InferiorTemplate;
}
}
and the XAML :
和 XAML :
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<TextBox Name="theValue" Grid.Row="0">1</TextBox>
<ContentControl Grid.Row="2" Content="{Binding ElementName=theValue, Path=Text}" >
<ContentControl.ContentTemplateSelector>
<sel:InferiorSuperiorTemplateSelector ValueToCompare="12" SuperiorTemplate="{StaticResource posTemplate}" InferiorTemplate="{StaticResource negTemplate}" />
</ContentControl.ContentTemplateSelector>
</ContentControl>
</Grid>
This works pretty fine if valueToCompareparameter is set manually (here with 12). When I try to make this one dynamic, by applying a binding I got the following error :
如果手动设置valueToCompare参数(此处为 12),则此方法非常有效。当我尝试使这个动态化时,通过应用绑定,我收到以下错误:
A 'Binding' cannot be set on the 'ValueToCompare' property of type 'InferiorSuperiorTemplateSelector'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.
无法在“InferiorSuperiorTemplateSelector”类型的“ValueToCompare”属性上设置“Binding”。只能在 DependencyObject 的 DependencyProperty 上设置“绑定”。
And here comes the problem : how can we declare a DependencyProperty in a DataTemplateSelector or is there any other option to acheve this goal ? I tried to define a dependencyproperty using the usual way but I can't resole the SetValue and GetValue methods.
问题来了:我们如何在 DataTemplateSelector 中声明一个 DependencyProperty 或者是否有其他选择来实现这个目标?我尝试使用通常的方式定义依赖项属性,但我无法重新定义 SetValue 和 GetValue 方法。
Thanks by advance.
提前致谢。
EDIT : As an appendix of the solution mentionned above, here is the fixed XAML code of my sample.
编辑:作为上面提到的解决方案的附录,这里是我的示例的固定 XAML 代码。
<TextBox Name="theValue" Grid.Row="0">1</TextBox>
<TextBox Name="theValueToCompare" Grid.Row="1">50</TextBox>
<ContentControl Grid.Row="2" Content="{Binding ElementName=theValue, Path=Text}"
local:DataTemplateParameters.ValueToCompare="{Binding ElementName=theValueToCompare, Path=Text}">
<ContentControl.ContentTemplateSelector>
<local:InferiorSuperiorTemplateSelector SuperiorTemplate="{StaticResource posTemplate}" InferiorTemplate="{StaticResource negTemplate}" />
</ContentControl.ContentTemplateSelector>
</ContentControl>
The other parts of the code are similar.
代码的其他部分类似。
回答by Rohit Vats
As evident from the error you can only bind with dependency property.
But since it's already inheriting from DataTemplateSelector, you cannot inherit from DependencyObject class.
从错误中可以明显看出,您只能绑定依赖属性。但由于它已经继承自DataTemplateSelector,您不能从 DependencyObject 类继承。
So, I would suggest to create an Attached propertyfor binding purpose. But catch is attached property can only be applied on class deriving from DependencyObject.
因此,我建议为绑定目的创建一个附加属性。但是 catch 附加属性只能应用于从 DependencyObject 派生的类。
So, you need to tweak a bit to get it working for you. Let me explain step by step.
所以,你需要稍微调整一下才能让它为你工作。让我一步一步解释。
First- Create attached property as suggested above:
首先- 按照上面的建议创建附加属性:
public class DataTemplateParameters : DependencyObject
{
public static double GetValueToCompare(DependencyObject obj)
{
return (double)obj.GetValue(ValueToCompareProperty);
}
public static void SetValueToCompare(DependencyObject obj, double value)
{
obj.SetValue(ValueToCompareProperty, value);
}
public static readonly DependencyProperty ValueToCompareProperty =
DependencyProperty.RegisterAttached("ValueToCompare", typeof(double),
typeof(DataTemplateParameters));
}
Second- Like I said it can be set only on object deriving from DependencyObject, so set it on ContentControl:
第二- 就像我说的,它只能在从 DependencyObject 派生的对象上设置,所以在 ContentControl 上设置它:
<ContentControl Grid.Row="2" Content="{Binding Path=PropertyName}"
local:DataTemplateParameters.ValueToCompare="{Binding DecimalValue}">
<ContentControl.ContentTemplateSelector>
<local:InferiorSuperiorTemplateSelector
SuperiorTemplate="{StaticResource SuperiorTemplate}"
InferiorTemplate="{StaticResource InferiorTemplate}" />
</ContentControl.ContentTemplateSelector>
</ContentControl>
Third. - Now you can get the value inside template from container object passed as parameter. Get Parent (ContentControl) using VisualTreeHelper and get value of attached property from it.
第三。- 现在您可以从作为参数传递的容器对象中获取模板内的值。使用 VisualTreeHelper 获取 Parent (ContentControl) 并从中获取附加属性的值。
public override System.Windows.DataTemplate SelectTemplate(object item,
System.Windows.DependencyObject container)
{
double dpoint = Convert.ToDouble(item);
double valueToCompare = (double)VisualTreeHelper.GetParent(container)
.GetValue(DataTemplateParameters.ValueToCompareProperty); // HERE
// double valueToCompare = (container as FrameworkElement).TemplatedParent;
return (dpoint >= valueToCompare) ? SuperiorTemplate : InferiorTemplate;
}
Also you can get ContentControl like this (container as FrameworkElement).TemplatedParent.
你也可以像这样获得 ContentControl (container as FrameworkElement).TemplatedParent。

