Silverlight 中的强制转换不起作用

发布于 2024-12-02 14:12:16 字数 2078 浏览 0 评论 0原文

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

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 只是一个显示值的虚拟控件。

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

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

提前致谢

I've a custom control look like this:

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

The TextBox is just a dummy to show the value.

Now when I add this control to an Application, I am able to set the Slider value greater than 7, although the value of my DependencyProperty is set to 7.

What I am doing wrong? Does the TwoWayBinding does not work in this situation?

Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小…红帽 2024-12-09 14:12:16

我的重现步骤:-

  • 在 VS2010 中创建一个全新的 Silverlight 应用程序,调用 SilverlightApplication1。
  • 将新的“Silverlight 模板化控件”添加到 silverlight 项目,并将其命名为“MyControl”。
  • 将 ControlTemplate 的内部内容复制到主题/Generic.xaml 文件的 ControlTemplate 中。整个通用文件如下所示:-

    <样式 TargetType="local:MyControl">
        
            <设置器.值>
                
                    <网格>
                        
                            <行定义高度=“20”/>
                            <行定义高度=“20”/>
                        
                        
                        
                    
    
                
            
        
    
    

    • 复制您的 C# 并将其放入 MyControl.cs 中。整个文件如下所示:-

using 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 的实例,现在看起来像:-

    
    
        <网格x:名称=“LayoutRoot”背景=“白色”>
            <本地:MyControl />
         
    
     
    
  • 运行解决方案,工作正常。

Steps for my repro:-

  • Create a fresh new Silverlight Application in VS2010 call SilverlightApplication1.
  • Add new "Silverlight Templated Control" to the silverlight project, naming it "MyControl".
  • Copied the inner contents or you ControlTemplate into the ControlTemplate of the themes/Generic.xaml file. This Entire generic file looks like:-

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

    • Copied your C# placed in in MyControl.cs. The whole file looks like:-

using System.Windows;
using 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;
        }

    }
}
  • Added an instance of MyControl to MainPage.xaml, which now looks like:-

    <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>
    
  • Run the solution, works fine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文