Бих искал да разширя някои стандартни UIElements в моя WPF. В идеалния случай би било добро решение да се използват прикачени свойства. Но не успях да го направя.
В моя ViewModel имам колекция от персонализирани обекти:
private ObservableCollection<ValidationFailure> validationFailures = new ObservableCollection<ValidationFailure>();
public ObservableCollection<ValidationFailure> ValidationFailures
{
get { return validationFailures; }
set
{
validationFailures = value;
OnPropertyChanged(() => ValidationFailures);
}
}
Това е, което бих искал да обвържа с моето прикачено свойство. Според мен аз също го обвързвам като ItemsSource на ListBox. Показва промените и всичко правилно, затова мисля, че колекцията уведомява добре.
Според мен го свързвам със следния код:
<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 пъти, променя обратното извикване веднъж, но след като (формулярът е зареден) променям колекцията в моята виртуална машина и въз основа на колекцията конверторът променя върната стойност, прикачените обратни извиквания на свойства не се задействат, както очаквах. Какво сбърках?