【发布时间】:2011-12-21 09:19:21
【问题描述】:
我想在我的 WPF 中扩展一些标准的 UIElements。理想情况下,使用附加属性将是一个很好的解决方案。但我没能做到。
在我的 ViewModel 中,我有一组自定义对象:
private ObservableCollection<ValidationFailure> validationFailures = new ObservableCollection<ValidationFailure>();
public ObservableCollection<ValidationFailure> ValidationFailures
{
get { return validationFailures; }
set
{
validationFailures = value;
OnPropertyChanged(() => ValidationFailures);
}
}
这就是我想绑定到我的附加属性的内容。在我看来,我还将它绑定为 ListBox 的 ItemsSource。它正确显示了更改和所有内容,这就是我认为该集合通知良好的原因。
在我看来,我将它与以下代码绑定:
<TextBox x:Name="ssn" Grid.Row="0" Grid.Column="1" Margin="10,0,0,0"
Text="{Binding PatientAggRoot.Patient.Ssn}"
Background="{Binding Path=CheckSsnButtonBackground}"
Validation:ValidationErrorAttached.HasValidationErrors="{Binding ValidationFailures,Converter={x:Static Converters:ConvertersHolder.ValidationErrorsLookupConverter},ConverterParameter='SSN',Mode=OneWay}"
/>
我的转换器如下所示:
public class ValidationErrorsLookupConverter : IValueConverter
{
#region IValueConverter implementation
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
if (value != null)
{
var validationLookup = (ObservableCollection<ValidationFailure>)value;
bool hasErrors = validationLookup.Any(vf => vf.Key == ((string) parameter));
return hasErrors;
}
return null;
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
throw new NotImplementedException("Can't convert back");
}
#endregion
}
我测试了转换器参数,它在列表框上也能正常工作; 最后是我的附加属性:
public static readonly DependencyProperty HasValidationErrorsProperty = DependencyProperty.RegisterAttached("HasValidationErrors", typeof(Boolean), typeof(ValidationErrorAttached), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnChangeCallBack, OnCoerceValueChanged));
private static object OnCoerceValueChanged(DependencyObject d, object basevalue)
{
//throw new NotImplementedException();
return basevalue;
}
private static void OnChangeCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
//throw new NotImplementedException();
if (((bool)e.NewValue))
{
((TextBox) d).BorderBrush = Brushes.Red;
}
}
public static void SetHasValidationErrors(UIElement element, Boolean value)
{
element.SetValue(HasValidationErrorsProperty, value);
}
public static Boolean GetHasValidationErrors(UIElement element)
{
return (Boolean)element.GetValue(HasValidationErrorsProperty);
}
它在 ValidationErrorAttached 类中,它是一个 Freezable 类。
当我打开包含上述文本框的表单时,附加属性的 coervalue 被触发 2 次,更改回调一次,但之后(加载表单)我更改了我的 VM 中的集合,并基于集合转换器更改返回值,附加属性回调不会像我预期的那样触发。我做错了什么?
【问题讨论】:
-
默认有验证错误吗?
-
一般情况下可能有,但在我的测试用例中没有:很快没有。但集合不是空的,只是空的。
-
这就像他们的问题 - 它会接收 Collection.Add 事件吗?
-
我需要习惯如何编写 cmets,所以再次:靠近一点。为了澄清这个场景:我的虚拟机中有一个验证器,如果视图发生变化,它就会运行。以下是相关代码:`patientMainViewModel.ValidationFailures.Clear();整数解析; if (!Int32.TryParse(patientMainViewModel.PatientAggRoot.Patient.Ssn, out parse)) { patientMainViewModel.ValidationFailures.Add(new ValidationFailure("SSN", "Taj szám nem csak számokból áll")); }` 现在的问题是,我的转换器也没有运行。你有想法吗?
-
在 Mode 之后尝试绑定 PresentationTraceSources.TraceLevel=High。它有效吗?给它任何错误?它有什么显示吗?
标签: c# wpf binding mvvm attached-properties