【发布时间】:2011-03-20 09:40:59
【问题描述】:
我正在编写一个真正的NumericUpDown/Spinner 控件作为学习自定义控件创作的练习。我有我正在寻找的大部分行为,包括适当的强制。然而,我的一项测试发现了一个缺陷。
我的控件有 3 个依赖属性:Value、MaximumValue 和 MinimumValue。我使用强制来确保Value 保持在最小值和最大值之间,包括在内。例如:
// In NumericUpDown.cs
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(int), typeof(NumericUpDown),
new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.Journal, HandleValueChanged, HandleCoerceValue));
[Localizability(LocalizationCategory.Text)]
public int Value
{
get { return (int)this.GetValue(ValueProperty); }
set { this.SetCurrentValue(ValueProperty, value); }
}
private static object HandleCoerceValue(DependencyObject d, object baseValue)
{
NumericUpDown o = (NumericUpDown)d;
var v = (int)baseValue;
if (v < o.MinimumValue) v = o.MinimumValue;
if (v > o.MaximumValue) v = o.MaximumValue;
return v;
}
我的测试只是为了确保数据绑定按我的预期工作。我创建了一个默认的 wpf windows 应用程序并输入了以下 xaml:
<Window x:Class="WpfApplication.MainWindow" x:Name="This"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:nud="clr-namespace:WpfCustomControlLibrary;assembly=WpfCustomControlLibrary"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<nud:NumericUpDown Value="{Binding ElementName=This, Path=NumberValue}"/>
<TextBox Grid.Row="1" Text="{Binding ElementName=This, Path=NumberValue, Mode=OneWay}" />
</Grid>
</Window>
使用非常简单的代码隐藏:
public partial class MainWindow : Window
{
public int NumberValue
{
get { return (int)GetValue(NumberValueProperty); }
set { SetCurrentValue(NumberValueProperty, value); }
}
// Using a DependencyProperty as the backing store for NumberValue. This enables animation, styling, binding, etc...
public static readonly DependencyProperty NumberValueProperty =
DependencyProperty.Register("NumberValue", typeof(int), typeof(MainWindow), new UIPropertyMetadata(0));
public MainWindow()
{
InitializeComponent();
}
}
(我省略了控件演示的 xaml)
现在,如果我运行它,我会看到来自 NumericUpDown 的值正确反映在文本框中,但如果我输入超出范围的值,则超出范围的值会显示在测试文本框中,而 NumericUpDown显示正确的值。
这就是强制价值观应该如何行动吗?在 ui 中强制它很好,但我希望强制值也能贯穿数据绑定。
【问题讨论】:
-
似乎绑定不支持考虑 val。你试过 TextBox 的 diff 模式吗?
标签: c# wpf xaml data-binding dependency-properties