Принуждение в Silverlight не работает - PullRequest
1 голос
/ 01 сентября 2011

У меня есть пользовательский элемент управления, похожий на этот:

generic.xaml

<Style TargetType="controls:MyControl">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="controls:MyControl">
        <Grid>
          <Grid.RowDefinitions>
            <RowDefinition Height="20" />
            <RowDefinition Height="20" />
          </Grid.RowDefinitions>
          <TextBox Grid.Row="0"
                   Text="{Binding ElementName=slider, Path=Value}" />
          <Slider Grid.Row="1" Name="slider" Width="120"
                  Minimum="1" Maximum="12"
                  Value="{Binding Mode=TwoWay,
                          RelativeSource={RelativeSource TemplatedParent},
                          Path=Value}"/>
        </Grid>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

MyControl.cs

public static readonly DependencyProperty ValueProperty =
  DependencyProperty.Register("Value",
  typeof(double),
  typeof(MyControl),
  new PropertyMetadata(0d, OnValueChanged));

  public double Value
  {
    get { return (double)base.GetValue(ValueProperty); }
    set { base.SetValue(ValueProperty, value); }
  }

  private static void OnValueChanged(DependencyObject source,
                                     DependencyPropertyChangedEventArgs e)
  {
    MyControl myControl = (MyControl)source;
    myControl.OnValueChanged((double)e.OldValue, (double)e.NewValue);
  }

  protected virtual void OnValueChanged(double oldValue, double newValue)
  {
    double coercedValue = CoerceValue(newValue);
    if (coercedValue != newValue)
    {
      this.Value = coercedValue;
    }
  }

  private double CoerceValue(double value)
  {
    double limit = 7;
    if (value > limit)
    {
      return limit;
    }
    return value;
  }

TextBox является просто фиктивнымпоказать значение.

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

ЧтоЯ делаю не так?Разве TwoWayBinding не работает в этой ситуации?

Заранее спасибо

1 Ответ

1 голос
/ 01 сентября 2011

Шаги для моего воспроизведения: -

  • Создайте новое приложение Silverlight в VS2010, вызов SilverlightApplication1.
  • Добавьте новый «Шаблон управления Silverlight» в проект silverlight, назвав его «MyControl».
  • Скопировал внутреннее содержимое или ваш ControlTemplate в ControlTemplate файла themes / Generic.xaml. Весь этот общий файл выглядит так: -

    <Style TargetType="local:MyControl">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:MyControl">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="20" />
                            <RowDefinition Height="20" />
                        </Grid.RowDefinitions>
                        <TextBox Grid.Row="0"
                       Text="{Binding ElementName=slider, Path=Value}" />
                        <Slider Grid.Row="1" Name="slider" Width="120"
                      Minimum="1" Maximum="12"
                      Value="{Binding Mode=TwoWay,
                              RelativeSource={RelativeSource TemplatedParent},
                              Path=Value}"/>
                    </Grid>
    
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    • Скопировал ваш C # в MyControl.cs. Весь файл выглядит так: -

с использованием System.Windows; используя System.Windows.Controls;

namespace SilverlightApplication1
{
    public class MyControl : Control
    {
        public MyControl()
        {
            this.DefaultStyleKey = typeof(MyControl);
        }

        public static readonly DependencyProperty ValueProperty =
  DependencyProperty.Register("Value",
  typeof(double),
  typeof(MyControl),
  new PropertyMetadata(0d, OnValueChanged));

        public double Value
        {
            get { return (double)base.GetValue(ValueProperty); }
            set { base.SetValue(ValueProperty, value); }
        }

        private static void OnValueChanged(DependencyObject source,
                                           DependencyPropertyChangedEventArgs e)
        {
            MyControl myControl = (MyControl)source;
            myControl.OnValueChanged((double)e.OldValue, (double)e.NewValue);
        }

        protected virtual void OnValueChanged(double oldValue, double newValue)
        {
            double coercedValue = CoerceValue(newValue);
            if (coercedValue != newValue)
            {
                this.Value = coercedValue;
            }
        }

        private double CoerceValue(double value)
        {
            double limit = 7;
            if (value > limit)
            {
                return limit;
            }
            return value;
        }

    }
}
...