2014-02-25 93 views
7

我想設計一個DataTemplateSelector誰比較有一個參數傳遞給定的值,然後選擇合適的模板,如果該值的優劣一個屬性綁定到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; 
    } 
} 

和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> 

這個工作,如果valueToCompare參數設置馬精緻漂亮nual(這裏是12)。 當我試圖讓這一個動態的,通過應用結合我得到了以下錯誤:

A「綁定」不能在 類型的「ValueToCompare」屬性設置「InferiorSuperiorTemplateSelector」。 「綁定」只能在DependencyObject的DependencyProperty上設置。

問題來了:我們如何在DataTemplateSelector中聲明一個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> 

代碼的其他部分是相似的。

+0

什麼是您的「常用方式」,您對SetValue和GetValue有什麼問題?數據綁定在後臺執行,所以你只需要那些從你的代碼中獲取和設置值,並且給它只是一個雙倍的數據,我不明白爲什麼會有問題。 –

+0

問題在於你需要繼承'DataTemplateSelector'和'DependencyObject'。你不能。 – Aron

+0

對我來說,通常的方式如下所示: public Boolean State {return(Boolean)this.GetValue(StateProperty); } set {this.SetValue(StateProperty,value); } } public static readonly DependencyProperty StateProperty = DependencyProperty.Register( 「State」,typeof(Boolean),typeof(MyStateControl),new PropertyMetadata(false)); 而根據阿隆,這將需要從DependencyObject繼承,這是不可能的。 那麼,有沒有什麼解決方法? – eka808

回答

11

從錯誤中可以看出,您只能綁定依賴項屬性。 但由於它已經從DataTemplateSelector繼承,所以不能從DependencyObject類繼承。

因此,我建議創建一個Attached property爲約束力的目的。但是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)); 

} 

- 就像我說的,只能在對象自DependencyObject派生進行設置,因此將其放置在ContentControl中:

​​

第三。 - 現在,您可以從作爲參數傳遞的容器對象中獲取模板中的值。使用VisualTreeHelper獲取父項(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; 
} 

你也可以像這樣得到ContentControl (container as FrameworkElement).TemplatedParent

+1

+1:你在我之前:),對我來說一切工作正常。 –

+0

@Anatoily - 很想聽聽你的方法。你是在同一思路還是其他方法? –

+0

我也是這樣做的。當控件未完全加載時,我試圖在'PropertyChanged'處理程序中獲取附加依賴項屬性的唯一值 - 不斷髮生這樣的錯誤。 –