在WPF中,隐藏控件时如何隐藏验证错误模板装饰(默认情况下为红色框)?当我隐藏我的控件(以便于在视图之间切换)时,错误装饰会一直存在。
更难,我如何使用MVVM做到这一点?
答案 0 :(得分:7)
ControlTemplate
的默认Validation.ErrorTemplate
有一个AdornedElementPlaceholder
,而AdornedElement
则会引用其<ControlTemplate>
<Border BorderBrush="Red" BorderThickness="1">
<AdornedElementPlaceholder />
</Border>
</ControlTemplate>
。看起来像这样
Border
从此处可以将AdornedElementPlaceholder.AdornedElement
的可见性与Control
的可见性绑定,以链接其可见性。然后,我们将具有此问题的所有Validation.ErrorTemplate
设为使用此<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}">
而不是默认值UserControl
。这是一个例子
Xaml
Parent
<强>更新强>
要在绑定中引用父TextBox
,您可以
1.对于特定控件,您可以使用StackPanel
属性
示例:如果UserControl
位于<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>
中的ResourceDictionary
,我们可以使用Parent.Parent
Border
2.对于更动态的方法,您可以使用带有代码隐藏文件的UserControl
,其中您可以使用<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>
的Loaded事件。在其中,您沿着可视树向上查找父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;
}
}
并将其用作绑定的来源
ValidationErrorTemplateDictionary.xaml
<UserControl ...>
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ValidationErrorTemplateDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<StackPanel>
<TextBox ...
Validation.ErrorTemplate="{StaticResource ValidationErrorTamplate3}">
ValidationErrorTemplateDictionary.xaml.cs
{{1}}
您的UserControl
{{1}}
答案 1 :(得分:0)
我必须解决这个问题,因为可见性和不透明度。
我是通过创建一个继承的附加属性来实现的,我将数据绑定到ErrorTemplate的可见性和不透明度。在父元素(淡入和淡出/折叠的实际元素)上,我只是将新附加属性分别绑定到可见性和不透明度。
此方法使用WPF的逻辑树和现有属性值继承来解决问题,而无需代码隐藏,或者您的模板具体了解可见性控制父级将是什么。
事后看来,我可以创建一个FrameWorkElement类型的附加属性,然后我可以使用它来绑定父元素上的任何属性。这种方法将涉及更少的绑定和更少的代码实现,同时提供更多的灵活性。也许已经存在附属属性让你做同样的事情。
您可以在此处阅读所有有关附加属性的内容:http://msdn.microsoft.com/en-us/library/ms749011.aspx
或者,这是一个很好的堆栈: How exactly do Attached Properties work in WPF?