当我的wpf绑定验证失败并且包含的​​面板不再可见时,如何摆脱红色矩形?

Sam*_*rum 21 .net c# data-binding validation wpf

我有一种情况,我使用ExceptionValidationRule使用wpf数据绑定和验证.

解决方案的另一部分invovles折叠一些面板并显示其他面板.

如果设置了验证异常 - 即UI在UI元素周围显示带有验证问题的红色边框,并且包含的​​面板已折叠,则仍会显示红色边框.这显然不是意味着什么?这有解决方法吗?任何人都知道这是否是设计的?

提供的最小代码示例(不是我的实际代码,但复制问题).创建一个新的WpfApplication(我称之为WpfDataBindingProblem).

window1的xaml如下:

<Window x:Class="WpfDataBindingProblem.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <StackPanel Margin="5">

        <StackPanel Name="panel1" Visibility="Visible" Margin="5">
            <TextBox Name="DataBoundTextBox">
                <Binding Path="TextValue">
                    <Binding.ValidationRules>
                        <ExceptionValidationRule/>
                    </Binding.ValidationRules>
                </Binding>
            </TextBox>
        </StackPanel>

        <StackPanel Name="panel2" Visibility="Collapsed" Margin="5">
            <TextBlock>
                The quick brown fox jumps over the lazy dog.
            </TextBlock>
        </StackPanel>

        <Button Click="Button_Click" Margin="5">
            Toggle panels
        </Button>

    </StackPanel>
</Window>
Run Code Online (Sandbox Code Playgroud)

window1的代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfDataBindingProblem {

    public partial class Window1 : Window {
        public Window1() {
            InitializeComponent();

            this.DataContext = new MyClass("default");
        }

        private void Button_Click(object sender, RoutedEventArgs e) {
            panel1.Visibility = panel1.Visibility == Visibility.Collapsed ?
                Visibility.Visible : Visibility.Collapsed;
            panel2.Visibility = panel2.Visibility == Visibility.Collapsed ?
                Visibility.Visible : Visibility.Collapsed;
        }
    }

    public class MyClass : INotifyPropertyChanged {

        private string mTextValue;

        public MyClass(string defaultText) {
            TextValue = defaultText;
        }

        public string TextValue {
            get {
                return mTextValue;
            }
            set {
                mTextValue = value;
                if (string.IsNullOrEmpty(mTextValue)) {
                    throw new ApplicationException("Text value cannot be empty");
                }
                OnPropertyChanged(new PropertyChangedEventArgs("TextValue"));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) {
            if (this.PropertyChanged != null) {
                this.PropertyChanged(this, e);
            }
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

要重现该问题,请运行该应用程序.从文本框和选项卡中删除默认文本 - 显示红色矩形表示验证问题.单击按钮.隐藏包含红色矩形控件的面板,显示另一个面板,但红色矩形仍然存在.AARGH!

所有人都非常感谢.

PS道歉很长的问题!

Don*_*lle 23

如果我没记错的话,这是一个众所周知的问题.我们重新模板化文本框以包含以下内容:

<Setter Property="Validation.ErrorTemplate">
    <Setter.Value>
        <ControlTemplate>
            <ControlTemplate.Resources>
                <BooleanToVisibilityConverter x:Key="converter" />
        </ControlTemplate.Resources>
            <DockPanel LastChildFill="True">
                <Border 
                    BorderThickness="1"
                    BorderBrush="Red"
                    Visibility="{Binding ElementName=placeholder, Mode=OneWay, Path=AdornedElement.IsVisible, Converter={StaticResource converter}}">
                    <AdornedElementPlaceholder x:Name="placeholder" />
                </Border>
             </DockPanel>
         </ControlTemplate>
    </Setter.Value>
</Setter>
Run Code Online (Sandbox Code Playgroud)