将属性绑定到DataTemplateSelector

eka*_*808 8 wpf xaml

我想设计一个DataTemplateSelector,它将给定的值与传入的参数进行比较,如果值优于或低于,则选择正确的模板

我带来了以下内容:

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

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

如果手动设置valueToCompare参数(此处为12),这可以正常工作.当我尝试使这个动态,通过应用绑定我得到以下错误:

无法在"InferiorSuperiorTemplateSelector"类型的"ValueToCompare"属性上设置"绑定".'绑定'只能在DependencyObject的DependencyProperty上设置.

问题就出现了:如何在DataTemplateSelector中声明DependencyProperty,还是有其他选项来实现这个目标?我尝试使用常规方法定义dependencyproperty但我无法解析SetValue和GetValue方法.

谢谢你提前.

编辑:作为上面提到的解决方案的附录,这是我的样本的固定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>
Run Code Online (Sandbox Code Playgroud)

代码的其他部分是类似的.

Roh*_*ats 12

从错误中可以看出,您只能与依赖项属性绑定.但由于它已经继承DataTemplateSelector,因此无法从DependencyObject类继承.

所以,我建议创建一个Attached属性用于绑定目的.但是catch附加属性只能应用于从DependencyObject派生的类.

所以,你需要调整一下才能让它适合你.让我一步一步解释.


首先 - 按照上面的建议创建附加属性:

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

}
Run Code Online (Sandbox Code Playgroud)

第二 - 就像我说它只能在从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>
Run Code Online (Sandbox Code Playgroud)

第三. - 现在您可以从作为参数传递的容器对象中获取模板内的值.使用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;
}
Run Code Online (Sandbox Code Playgroud)

你也可以这样得到ContentControl (container as FrameworkElement).TemplatedParent.