Hide validation when hiding a control

How, in WPF, do you hide the validation error pattern decoration (the red box by default) when you hide the control? When I hide my controls (to make it easier to switch between views), decorating bugs sticks around.

Even harder how to do this using MVVM?

+4
source share
2 answers

By default, the ControlTemplate for Validation.ErrorTemplate has an AdornedElementPlaceholder , which in turn has a link to its AdornedElement . Looks like this

 <ControlTemplate> <Border BorderBrush="Red" BorderThickness="1"> <AdornedElementPlaceholder /> </Border> </ControlTemplate> 

From here, you can associate Border visibility with the AdornedElementPlaceholder.AdornedElement visibility to associate their visibility. Then we create all Control that have this problem using this Validation.ErrorTemplate instead of the standard one. Here is an example

Xaml

 <Window.Resources> <ControlTemplate x:Key="ValidationErrorTamplate"> <Border Visibility="{Binding ElementName=placeHolder, Path=AdornedElement.Visibility}" BorderBrush="Red" BorderThickness="1"> <AdornedElementPlaceholder x:Name="placeHolder"/> </Border> </ControlTemplate> </Window.Resources> <TextBox ... Validation.ErrorTemplate="{StaticResource ValidationErrorTamplate}"> 

Update
To reference the parent UserControl in the binding, you can

1. For a specific control, you can approach the logical tree using the Parent Property

An example . If the TextBox is in the StackPanel in the UserControl , we can reference it with Parent.Parent

 <UserControl ...> <StackPanel> <TextBox ... Validation.ErrorTemplate="{StaticResource ValidationErrorTamplate2}"> <ControlTemplate x:Key="ValidationErrorTamplate2"> <Border Visibility="{Binding ElementName=placeHolder, Path=AdornedElement.Parent.Parent.Visibility}" BorderBrush="Red" BorderThickness="1"> <AdornedElementPlaceholder x:Name="placeHolder"/> </Border> </ControlTemplate> 

2.For a more dynamic approach, you can use ResourceDictionary with the code behind the file in which you use the Loaded event for Border . In it, you look at the visual tree to find the parent UserControl and use it as a binding source

ValidationErrorTemplateDictionary.xaml

 <ResourceDictionary x:Class="ValidationErrorVisibility.ValidationErrorTemplateDictionary" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <ControlTemplate x:Key="ValidationErrorTamplate3"> <Border BorderBrush="Red" BorderThickness="1" Loaded="ValidationAdorner_Loaded"> <AdornedElementPlaceholder/> </Border> </ControlTemplate> </ResourceDictionary> 

ValidationErrorTemplateDictionary.xaml.cs

 public partial class ValidationErrorTemplateDictionary { private void ValidationAdorner_Loaded(object sender, RoutedEventArgs e) { Border adornedBorder = sender as Border; Binding visibilityBinding = new Binding("Visibility"); UIElement adornedElement = ((AdornedElementPlaceholder)adornedBorder.Child).AdornedElement; UserControl parentUserControl = GetVisualParent<UserControl>(adornedElement); visibilityBinding.Source = parentUserControl; adornedBorder.SetBinding(Border.VisibilityProperty, visibilityBinding); } public static T GetVisualParent<T>(object childObject) where T : Visual { DependencyObject child = childObject as DependencyObject; while ((child != null) && !(child is T)) { child = VisualTreeHelper.GetParent(child); } return child as T; } } 

Your usercontrol

 <UserControl ...> <UserControl.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="ValidationErrorTemplateDictionary.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </UserControl.Resources> <StackPanel> <TextBox ... Validation.ErrorTemplate="{StaticResource ValidationErrorTamplate3}"> 
+7
source

I just had to solve this problem for visibility and opacity.

I did this by creating an inherited attached property, which I data ties the visibility and opacity of the ErrorTemplate. In the parent element (the actual element that fades and fades / collapses), I simply bind the new attached properties to visibility and opacity, respectively.

This method uses the WPF logical tree and the existing inheritance of the property value to solve the problem without the code behind or the specific knowledge of your template about what will be the controlling parent.

In retrospect, I could create one attached property of type FrameWorkElement, which can then be used to bind to any property of the parent element. This approach will include less binding and less code to achieve, while providing less flexibility. The attached property may already exist so you can do the same.

You can read all about related properties here: http://msdn.microsoft.com/en-us/library/ms749011.aspx

Alternatively, this is a good stack: How do nested properties work in WPF?

0
source

Source: https://habr.com/ru/post/1337838/


All Articles