2011-04-14 66 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