自定义控件中的TemplateBindings

时间:2009-04-16 12:21:35

标签: silverlight-2.0 templatebinding

我只是在使用Silverlight中的自定义控件,而对于我的生活,我无法使TemplateBindings工作。有人可以给这个简化版本一次,看看我是否遗漏了什么。

所以我在generic.xaml中的ControlTemplate看起来像

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:NumericStepperControl;assembly=NumericStepperControl">
    <Style TargetType="local:NumericStepper">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:NumericStepper">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition />
                            <ColumnDefinition />
                        </Grid.ColumnDefinitions>

                        <Border Grid.Column="0" BorderBrush="Black" BorderThickness="2"  Width="50" Height="30">
                            <TextBlock Width="50" Height="30" Text="{TemplateBinding Value}" />
                        </Border>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>        
        </Setter>
    </Style>
</ResourceDictionary>

我的控件类看起来像:

namespace NumericStepperControl
{
    public class NumericStepper : Control
    {
        public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(int), typeof(NumericStepper), new PropertyMetadata(20));

        public NumericStepper()
            : base()
        {
            DefaultStyleKey = typeof( NumericStepper );
        }

        public int Value
        {
            get
            {
                return (int)GetValue(ValueProperty);
            }
            set
            {
                SetValue(ValueProperty, value);
            }
        }
    }
}

我期待这次运行时TextBlock会显示数字20.任何关于为什么这不起作用的想法?

作为一方,我没有一个单独的项目,其中包含对NumericStepperControl程序集的引用,当它运行时,控件似乎正确构建。

编辑...经过一些调查后我发现如果我将Value属性的类型更改为一个正常工作的字符串。为什么文本块不仅仅在传入任何内容时调用toString?有没有办法围绕这个,因为我可以看到它发生了很多?

2 个答案:

答案 0 :(得分:11)

经过一番挖掘后发现TextBlock实际上并没有在传入的内容上调用ToString。要解决这个问题,你必须使用Converter为你调用ToString。

虽然这很简单,但TemplateBinding不支持转换器。您必须将TemplateBinding添加到DataContext,然后在Text属性中使用常规Binding以及转换器。

因此TextBlock标记变为

 <TextBlock Width="50" Height="30" DataContext="{TemplateBinding Value}"  Text="{Binding Converter={StaticResource NumberTypeToStringConverter}}" />

我的自定义转换器:

public class NumberTypeToStringConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null)
            {
                throw new NullReferenceException();
            } 

            return value.ToString(); 
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            MethodInfo methodInfo = targetType.GetMethod("Parse");

            if (methodInfo == null)
            {
                throw new MissingMethodException("The targetType to convert back to a Number must implement a Parse method");
            }

            return methodInfo.Invoke(null, new object[] { value });
        }
    }

这似乎是一种解决方法,我有兴趣听听它是否有任何不利影响。如果有人正在读这个并且我的转换器有任何问题,请告诉我。

干杯

答案 1 :(得分:0)

有不同的方法可以解决这个问题。 Found this description by Marek Latuskiewicz