4

我只是在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 ?有没有办法解决这个问题,因为我可以看到它发生了很多?

4

2 回答 2

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

这似乎是一种解决方法,我很想知道它是否有任何不利影响。另外,如果有人正在阅读本文并且我的转换器有任何问题,请告诉我。

干杯

于 2009-04-17T10:10:33.550 回答
0

有不同的方法可以解决这个问题。 找到 Marek Latuskiewicz 的描述

于 2010-02-14T20:45:59.490 回答