我有一个UserControl,将在我们正在开发的应用程序中重复使用。我们使用基于MVVMLight的框架。
为了简单起见,假设用户控件仅包含一个文本框并公开一个名为“Quantity”的依赖属性。用户控件上的文本框与依赖属性“Quantity”进行数据绑定。
当用户控件在视图上使用时,用户控件的“Quantity”依赖属性会与ViewModel中的属性进行数据绑定。(通过MVVMLight ViewModelLocator,此ViewModel是视图的数据上下文)。
这一切都很好!绑定有效,属性设置正常。直到涉及验证时才出现问题。
我们使用DataAnnotations来装饰ViewModel属性。ViewModel包含INotifyDataErrorInfo的自定义实现。我们已经为大多数输入控件实现了自定义样式,以显示控件周围的红色边框和消息,其中显示验证错误消息。所有这些在正常情况下(例如,View上的Textbox绑定到ViewModel中的属性)都非常好用。
当我尝试使用此用户控件采用相同的方法时,我得到的是整个用户控件周围的红色边框和实际文本框上没有错误指示。似乎UI反映了存在错误的事实,但它只是没有传递到我想要的控件上。
我在stackoverflow上搜索了这个问题,但在那些有解决方案的问题中,没有一个适用于我的情况。
我的第一个猜测是,由于实际文本框直接绑定到依赖属性本身而不是绑定到视图模型上的属性,因此它无法正确地通知生成的错误。是否有一种方法可以通过用户控件将在ViewModel中生成的这些错误传播到文本框?
非常感谢您提供的任何帮助或建议。
以下是UserControl xaml。
用户控件的代码后台。
视图模型属性。
为了简单起见,假设用户控件仅包含一个文本框并公开一个名为“Quantity”的依赖属性。用户控件上的文本框与依赖属性“Quantity”进行数据绑定。
当用户控件在视图上使用时,用户控件的“Quantity”依赖属性会与ViewModel中的属性进行数据绑定。(通过MVVMLight ViewModelLocator,此ViewModel是视图的数据上下文)。
这一切都很好!绑定有效,属性设置正常。直到涉及验证时才出现问题。
我们使用DataAnnotations来装饰ViewModel属性。ViewModel包含INotifyDataErrorInfo的自定义实现。我们已经为大多数输入控件实现了自定义样式,以显示控件周围的红色边框和消息,其中显示验证错误消息。所有这些在正常情况下(例如,View上的Textbox绑定到ViewModel中的属性)都非常好用。
当我尝试使用此用户控件采用相同的方法时,我得到的是整个用户控件周围的红色边框和实际文本框上没有错误指示。似乎UI反映了存在错误的事实,但它只是没有传递到我想要的控件上。
我在stackoverflow上搜索了这个问题,但在那些有解决方案的问题中,没有一个适用于我的情况。
我的第一个猜测是,由于实际文本框直接绑定到依赖属性本身而不是绑定到视图模型上的属性,因此它无法正确地通知生成的错误。是否有一种方法可以通过用户控件将在ViewModel中生成的这些错误传播到文本框?
非常感谢您提供的任何帮助或建议。
以下是UserControl xaml。
<UserControl x:Class="SampleProject.UserControls.SampleControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" x:Name="sampleControl"
d:DesignHeight="300" d:DesignWidth="300">
<Grid x:Name="LayoutRoot" DataContext="{Binding ElementName=sampleControl}">
<TextBox Text="{Binding Path=Quantity, ValidatesOnDataErrors=True}" Width="100" Height="30" />
</Grid>
</UserControl>
用户控件的代码后台。
public partial class SampleControl : UserControl
{
public SampleControl()
{
InitializeComponent();
}
public static readonly DependencyProperty QuantityProperty =
DependencyProperty.Register("Quantity", typeof(int?), typeof(SampleControl),
new FrameworkPropertyMetadata{DefaultValue=null, BindsTwoWayByDefault = true});
public int? Quantity
{
get { return (int?)GetValue(QuantityProperty); }
set { SetValue(QuantityProperty, value); }
}
}
用于视图。
<userControls:SampleControl Grid.Row="1" Quantity="{Binding Path=Quantity, ValidatesOnDataErrors=True}" Height="60" Width="300"/>
视图模型属性。
[Required(ErrorMessage = "Is Required")]
[Range(5, 10, ErrorMessage = "Must be greater than 5")]
public int? Quantity
{
get { return _quantity; }
set { Set(() => Quantity, ref _quantity, value); }
}
private int? _quantity;
(注意,setter中的Set方法只是基本视图模型中的辅助方法,用于设置后备属性并为其引发PropertyChanged事件。)