Tôi đang viết một kiểm soát thực sự NumericUpDown/Spinner
làm bài tập để tìm hiểu tác giả điều khiển tùy chỉnh. Tôi đã có hầu hết các hành vi mà tôi đang tìm kiếm, bao gồm cả cưỡng chế thích hợp. Tuy nhiên, một trong những thử nghiệm của tôi đã tiết lộ một lỗ hổng.Tại sao dữ liệu của tôi ràng buộc thấy giá trị thực thay vì giá trị bị cưỡng chế?
Kiểm soát của tôi có 3 thuộc tính phụ thuộc: Value
, MaximumValue
và MinimumValue
. Tôi sử dụng cưỡng chế để đảm bảo rằng Value
vẫn nằm trong khoảng từ min đến tối đa. Ví dụ:
// 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;
}
Thử nghiệm của tôi chỉ nhằm đảm bảo ràng buộc dữ liệu hoạt động như mong đợi. Tôi tạo ra một mặc định WPF cửa sổ ứng dụng và ném trong XAML sau:
<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>
với codebehind rất đơn giản:
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();
}
}
(Tôi bỏ qua XAML để trình bày của điều khiển)
Bây giờ nếu tôi chạy điều này, tôi thấy giá trị từ NumericUpDown
được phản ánh một cách thích hợp trong hộp văn bản, nhưng nếu tôi nhập giá trị nằm ngoài phạm vi, giá trị phạm vi được hiển thị trong hộp văn bản thử nghiệm trong khi NumericUpDown
hiển thị giá trị chính xác.
Đây có phải là cách các giá trị bị cưỡng chế được cho là hành động không? Thật tốt khi nó bị ép buộc trong ui, nhưng tôi cũng mong đợi giá trị bị ép buộc để chạy qua databinding.
Dường như ràng buộc không hỗ trợ đồng bộ hóa val. Bạn đã thử chế độ khác trong TextBox chưa? –