Я пишу настоящий 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
показывает правильное значение.
Так должны действовать принудительные значения?Хорошо, что он принудительно используется в пользовательском интерфейсе, но я ожидал, что приведенное значение также будет проходить через привязку данных.