自定义控件中的模板绑定

4

我正在尝试自定义Silverlight控件,但是我怎么也无法让TemplateBindings起作用。能否有人检查一下这个简化版本,看看我是否漏掉了什么。

所以我的ControlTemplate在generic.xaml中如下:

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

我期望当这个程序运行时,文本块将显示数字20。有什么想法为什么不起作用吗?
另外,我有一个单独的项目,其中包含对NumericStepperControl程序集的引用,当它运行时,控件似乎会正确构建。
编辑...经过更深入的调查后,我发现如果将Value属性的类型更改为字符串,则可以正常工作。为什么文本块不只是对传递给它的内容调用toString?有没有办法解决这个问题,因为我可以看到它经常发生?
2个回答

11

经过一番调查发现,TextBlock实际上没有对传入的内容调用ToString。为解决此问题,您必须使用转换器来代替调用ToString。

但是,TemplateBinding不支持转换器。您需要将TemplateBinding添加到DataContext中,然后在Text属性中使用普通绑定并配合转换器。

因此,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 });
        }
    }

这似乎是一个折中的方法,如果有不良影响,我很想听听意见。同时,如果有人在阅读此内容并且我的转换器有任何问题,请告诉我。

干杯


我刚刚花了一整天的时间来尝试解决这个问题。感谢詹姆斯发布了自己的答案 - 非常勤奋! - Mark Cooper

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接