2009-04-16 4 views
4

Я просто обманываю себя с помощью пользовательских элементов управления в silverlight, и для жизни меня я не могу заставить TemplateBindings работать. Может кто-то дать эту уменьшенную версию один раз, чтобы посмотреть, не хватает ли я чего-то.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); 
      } 
     } 
    } 
} 

Я ожидаю, когда это бежит TextBlock будет отображать номер 20. Любые идеи относительно того, почему это не работает?

В качестве стороны у меня нет отдельного проекта, который содержит ссылку на сборку NumericStepperControl и когда она запускается, элементы управления, похоже, правильно строятся.

Редактировать ... после немного большего количества исследований я обнаружил, что если я изменяю тип свойства Value на строку, которая работает нормально. Почему текстовый блок не просто вызывает toString на все, что передается в него? Есть ли способ обойти это, поскольку я вижу, что это происходит много?

ответ

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

Это кажется немного произведения вокруг и я бы интересно услышать, если он имеет какие-либо негативные последствия , Также, если кто-то читает это, и что-то не так с моим конвертером, пожалуйста, дайте мне знать.

Cheers

+0

Я просто сгорел почти на день, пытаясь понять это. Спасибо, что разместили свой собственный ответ Джеймс - очень прилежный !! –