问题描述
我只是在Silverlight中自定义控件,而对于我的一生,我无法让TemplateBindings正常工作.有人可以再给这个简化版本一次,看看我是否缺少某些东西.
I'm just mucking about with custom controls in silverlight and for the life of me i can't get the TemplateBindings to work. Can someone give this reduced version a once over to see if I'm missing something.
因此,我的generic.xaml中的ControlTemplate看起来像
So my ControlTemplate in the generic.xaml looks like
<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.关于为什么它不起作用的任何想法吗?
I'm expecting when this runs the TextBlock will display the number 20. Any ideas as to why this isn't working?
另一方面,我没有一个单独的项目,其中包含对NumericStepperControl程序集的引用,当它运行时,控件似乎可以正确构建.
As a side not i have a separate project which contains a ref to the NumericStepperControl assembly and when it runs the controls seem to build correctly.
编辑...经过更多调查,我发现如果我将Value属性的类型更改为可以正常工作的字符串.为什么文本块不只是在传递给它的对象上调用toString?我能看到很多事情发生吗?
推荐答案
经过一番挖掘,事实证明TextBlock实际上并未在传入的任何内容上调用ToString.要解决此问题,您必须使用Converter来为您调用ToString.
After a bit of digging it turns out that the TextBlock actually doesn't call ToString on whatever is passed in. To work around this you must use a Converter to call a ToString for you.
这很麻烦,TemplateBinding不支持Converters.您必须将TemplateBinding添加到DataContext,然后在Text属性中与转换器一起使用正常的Binding.
Here's the rub though, TemplateBinding doesn't support Converters. You have to add the TemplateBinding to the DataContext and then use normal Binding in the Text property along with the converter.
因此TextBlock标记变为
So the TextBlock markup becomes
<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 });
}
}
这似乎是一种解决方法,我很想知道它是否有任何不利影响.另外,如果有人正在阅读本文,而我的转换器有任何问题,请告诉我.
This seems like a bit of a work around and i'd be interested to hear if it has any adverse implications. Also if anyone is reading this and there is anything wrong with my converter please let me know.
欢呼
这篇关于自定义控件中的TemplateBindings的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!