2011-04-14 60 views
2

我正在工作一個非常簡單的無形控制,我似乎無法獲得模板綁定的工作之一。在控件中,我有兩個依賴屬性,一個是字符串,另一個是int。Silverlight的數據綁定詮釋無名控制不起作用

的CSHARP代碼如下所示:

using System; 
using System.Windows; 
using System.Windows.Controls; 

namespace ControlDemo 
{ 
    public class TextControlLookless : Control 
    { 
     #region Title 

     public static readonly DependencyProperty ChartTitleProperty = 
      DependencyProperty.Register("ChartTitle", typeof(string), typeof(TextControlLookless), 
      null); 


     public String ChartTitle 
     { 
      get { return (string)GetValue(ChartTitleProperty); } 
      set 
      { 
       SetValue(ChartTitleProperty, value); 
      } 
     } 

     #endregion 

     #region Value 

     public static readonly DependencyProperty ChartValueProperty = 
      DependencyProperty.Register("ChartValue", typeof(int), typeof(TextControlLookless), 
      null); 


     public int ChartValue 
     { 
      get { return (int)GetValue(ChartValueProperty); } 
      set 
      { 
       SetValue(ChartValueProperty, value); 
      } 
     } 

     #endregion 

     #region ctor 

     public TextControlLookless() 
     { 
      this.DefaultStyleKey = typeof(TextControlLookless); 
     } 

     #endregion 

    } 
} 

而且對於控制XAML看起來像這樣:

<ResourceDictionary 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:local="clr-namespace:ControlDemo"> 

<Style TargetType="local:TextControlLookless"> 
    <Setter Property="ChartTitle" Value="Set Title" /> 
    <Setter Property="ChartValue" Value="1" /> 

    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="local:TextControlLookless"> 
       <Grid x:Name="Root"> 
        <Border BorderBrush="Black" BorderThickness="2"> 
         <Grid> 
          <Grid.RowDefinitions> 
           <RowDefinition Height="Auto" /> 
           <RowDefinition Height="Auto" /> 
           <RowDefinition /> 
          </Grid.RowDefinitions> 
          <TextBlock Text="{TemplateBinding ChartTitle}" /> 
          <TextBlock Text="{TemplateBinding ChartValue}" Grid.Row="1" /> 
         </Grid> 
        </Border> 
       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

當我把這個頁面上,我可以看到ChartTitle(設置標題或我設置的任何內容),但ChartValue從不顯示。如果我將它的類型更改爲一個字符串,它會顯示出來,所以我必須丟失一些東西。

回答

0

問題是TemplateBinding是一個比Binding更原始的操作。 Binding是一個實際的類,包含一些有用的功能,包括字符串在其他數據類型之間的隱式轉換。

TemplateBinding純粹是一種標記指令,對您而言至關重要的是不會爲您進行類型轉換。因此,綁定到TextBlockText屬性的依賴項屬性必須是字符串。

你有兩個選擇: -

的一種選擇,而不是使用TemplateBinding給TextBlock的名稱,並指定其TextChartValue屬性更改回電話: -

#region Value 

    public static readonly DependencyProperty ChartValueProperty = 
     DependencyProperty.Register("ChartValue", typeof(int), typeof(TextControlLookless), 
     new PropertyMetadata(0, OnChartValuePropertyChanged)); 

    private static void OnChartValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     TextControlLookless source = d as TextControlLookless; 
     source.Refresh(); 
    } 


    public int ChartValue 
    { 
     get { return (int)GetValue(ChartValueProperty); } 
     set 
     { 
      SetValue(ChartValueProperty, value); 
     } 
    } 

    #endregion 

    private TextBlock txtChartValue { get; set; } 

    public override void OnApplyTemplate() 
    { 
     base.OnApplyTemplate(); 
     txtChartValue = GetTemplateChild("txtChartValue") as TextBlock; 
     Refresh(); 
    } 

    private void Refresh() 
    { 
     if (txtChartValue != null) 
     { 
      txtChartValue.Text = ChartValue.ToString(); 
     } 
    } 

在XAML看起來像: -

<TextBlock x:Name="txtChartValue" Grid.Row="1" /> 

另一種選擇是爲值創建一個私有依賴項屬性e爲字符串類型: -

 #region Value 

     public static readonly DependencyProperty ChartValueProperty = 
      DependencyProperty.Register("ChartValue", typeof(int), typeof(TextControlLookless), 
      new PropertyMetadata(0, OnChartValuePropertyChanged)); 

     private static void OnChartValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      d.SetValue(ChartValueStrProperty, e.NewValue.ToString()); 
     } 

     private static readonly DependencyProperty ChartValueStrProperty = 
      DependencyProperty.Register("ChartValueStr", typeof(string), typeof(TextControlLookless), 
      new PropertyMetadata("0")); 

     public int ChartValue 
     { 
      get { return (int)GetValue(ChartValueProperty); } 
      set 
      { 
       SetValue(ChartValueProperty, value); 
      } 
     } 

     #endregion 

在XAML看起來像: -

 <TextBlock Text="{TemplateBinding ChartValueStr}" Grid.Row="1" /> 

注意,ChartValueStrProperty是私人的,我沒有打擾創建一個標準的.NET屬性來覆蓋它。 TemplateBinding實際上將您分配的屬性名稱後綴與「屬性」一起使用,然後查找目標類型上的靜態字段。

這兩種方法都有其優點和缺點。第一種方法是更常見的模式,但需要更多的代碼並且不太靈活(顯示值的控件必須是TextBlock)。第二個是更靈活,使用較少的代碼,但有點非正統。

+0

我喜歡第二個如何工作,它似乎在我腦海中流動得更好。 – 2011-04-15 13:57:20