Ric*_*bob 32 validation wpf errortemplate
我有一个带有验证规则的TextBox,它位于TabControl的选项卡上.验证规则失败时,默认的ErrorTemplate正确显示(TextBox周围的红色边框).
但是,如果切换到另一个选项卡,然后使用TextBox返回选项卡,则ErrorTemplate hightlight将消失.如果TextBox中有更改,则仍会调用验证规则并返回false,但仍未显示错误突出显示.
只有当文本内容被更改为有效然后再次无效时才会重新亮相.
我希望如果文本内容无效,切换到另一个选项卡并返回保持无效突出显示.任何想要获得这种行为的想法都是最受欢
xaml:
<TextBox Height="35" >
<TextBox.Text>
<Binding Path="pan_id" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<ps:PanIdValidation />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
Run Code Online (Sandbox Code Playgroud)
Dyl*_*lan 59
TabItem应定义如下:
<TabItem Header="Foo">
<Border>
<AdornerDecorator>
<Grid>
<TextBox Height="35" >
<TextBox.Text>
<Binding Path="pan_id" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<ps:PanIdValidation />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</Grid>
</AdornerDecorator>
</Border>
</TabItem>
Run Code Online (Sandbox Code Playgroud)
问题是,Validation.Error提示是在Adorner Layer中绘制的.切换选项卡时,该图层将被丢弃.
Vit*_*cik 13
只是特殊情况的补充:我遇到了类似的问题,现在我正在使用类似于Dylan代码的解决方案.
区别在于我的TabItem包含GroupBox,TextBox在其中.在这种情况下,AdornerDecorator必须位于GroupBox本身,而不是TabItem的直接后代.
所以这不起作用:
<TabItem>
<AdornerDecorator>
<Grid>
<GroupBox>
<Grid>
<TextBox>...<TextBox/>
</Grid>
</GroupBox>
</Grid>
</AdornerDecorator>
</TabItem>
Run Code Online (Sandbox Code Playgroud)
但这样做:
<TabItem>
<Grid>
<GroupBox>
<AdornerDecorator>
<Grid>
<TextBox>...<TextBox/>
</Grid>
</AdornerDecorator>
</GroupBox>
</Grid>
</TabItem>
Run Code Online (Sandbox Code Playgroud)
我正在添加它,因为我无法轻易找到解决方案,甚至文档AdornerLayer.GetAdornerLayer()(虽然不确定它是否适用于此处)状态This static method traverses up the visual tree starting at the specified Visual and returns the first adorner layer found.- 但也许它也会在某些时候停止,这在文档中并不清楚.
正如Dylan解释的那样,这是因为在制表符开关上丢弃了用于绘制验证错误的Adorner层.所以你需要包装内容AdornerDecorator.
我创建了一个行为,一个包装Content的TabItem自动的AdornerDecorator,所以它不必须手动完成所有的TabItems.
public static class AdornerBehavior
{
public static bool GetWrapWithAdornerDecorator(TabItem tabItem)
{
return (bool)tabItem.GetValue(WrapWithAdornerDecoratorProperty);
}
public static void SetWrapWithAdornerDecorator(TabItem tabItem, bool value)
{
tabItem.SetValue(WrapWithAdornerDecoratorProperty, value);
}
// Using a DependencyProperty as the backing store for WrapWithAdornerDecorator. This enables animation, styling, binding, etc...
public static readonly DependencyProperty WrapWithAdornerDecoratorProperty =
DependencyProperty.RegisterAttached("WrapWithAdornerDecorator", typeof(bool), typeof(AdornerBehavior), new UIPropertyMetadata(false, OnWrapWithAdornerDecoratorChanged));
public static void OnWrapWithAdornerDecoratorChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
var tabItem = o as TabItem;
if (tabItem == null) return;
if(e.NewValue as bool? == true)
{
if (tabItem.Content is AdornerDecorator) return;
var content = tabItem.Content as UIElement;
tabItem.Content = null;
tabItem.Content = new AdornerDecorator { Child = content };
}
if(e.NewValue as bool? == false)
{
if (tabItem.Content is AdornerDecorator)
{
var decorator= tabItem.Content as AdornerDecorator;
var content = decorator.Child;
decorator.Child = null;
tabItem.Content = content;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以TabItems通过默认样式在所有行为上设置此行为:
<Style TargetType="TabItem">
<Setter Property="b:AdornerBehavior.WrapWithAdornerDecorator" Value="True"></Setter>
</Style>
Run Code Online (Sandbox Code Playgroud)
b 是行为所在的命名空间,类似这样(每个项目都会有所不同):
xmlns:b="clr-namespace:Styling.Behaviors;assembly=Styling"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5967 次 |
| 最近记录: |