1

我有一个自定义控件,如下所示:

通用的.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>

我的控制.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 只是显示值的虚拟对象。

现在,当我将此控件添加到应用程序时,我可以将 Slider 值设置为大于 7,尽管我的 DependencyProperty 的值设置为 7。

我做错了什么?TwoWayBinding 在这种情况下不起作用吗?

提前致谢

4

1 回答 1

1

我的复制步骤:-

  • 在 VS2010 调用 SilverlightApplication1 中创建一个全新的 Silverlight 应用程序。
  • 将新的“Silverlight Templated Control”添加到 silverlight 项目,将其命名为“MyControl”。
  • 将内部内容或您的 ControlTemplate 复制到主题/Generic.xaml 文件的 ControlTemplate 中。这个整个通用文件看起来像:-

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

    }
}
  • 向 MainPage.xaml 添加了一个 MyControl 实例,现在看起来像:-

    <UserControl x:Class="SilverlightApplication1.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:SilverlightApplication1"
        mc:Ignorable="d"
        d:DesignHeight="300" d:DesignWidth="400">
    
        <Grid x:Name="LayoutRoot" Background="White">
            <local:MyControl />
         </Grid>
    
     </UserControl>
    
  • 运行解决方案,工作正常。

于 2011-09-01T13:14:08.257 回答