Проблема в том, что TemplateBinding
является гораздо более примитивной операцией, чем Binding
. Binding
является реальным классом и включает некоторые полезные функции, включая неявное преобразование строк назад и вперед между другими типами данных.
TemplateBinding
является чисто инструкцией по разметке, и принципиально в вашем случае не выполняет преобразование типов для вас. Следовательно, свойство зависимости, связанное со свойством Text
для TextBlock
, должно быть строкой.
У вас есть два варианта: -
Вместо этого можно использовать TemplateBinding, присвоив TextBlock
имя и присвоив ему Text
в измененном обратном вызове свойства ChartValue
: -
#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" />
Другой вариант заключается в создании частного свойства зависимости для значения с типом строки: -
#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). Вторая более гибкая и использует меньше кода, но несколько неортодоксальна.