Как мне избавиться от красного прямоугольника, когда моя проверка привязки wpf не удалась и содержащая панель больше не видна? - PullRequest
21 голосов
/ 26 ноября 2008

У меня есть ситуация, когда я использую привязку и проверку данных wpf с помощью ExceptionValidationRule.

Другая часть решения включает в себя сворачивание одних панелей и отображение других.

Если установлено исключение проверки - то есть пользовательский интерфейс показывает красную рамку вокруг элемента пользовательского интерфейса с проблемой проверки, и содержащая панель свернута, красная граница по-прежнему отображается. Это явно не должно быть? Есть ли обходной путь для этого? Кто-нибудь знает, если это по замыслу?

Приведен пример минимального кода (не мой настоящий код, но повторяет проблему). Создайте новое приложение WpfApplication (я назвал его WpfDataBindingProblem).

xaml для window1 выглядит следующим образом:

<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>

Код для 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);
            }
        }
    }

}

Чтобы воспроизвести проблему, запустите приложение. Удалите текст по умолчанию из текстового поля, а вкладка не отображается - отображается красный прямоугольник, указывающий на проблему с проверкой. Нажмите на кнопку. Панель, содержащая элемент управления с красным прямоугольником, скрыта, и отображается другая панель, но красный прямоугольник остается. Aargh!

Вся помощь очень ценится.

PS извиняюсь за длинное название вопроса!

Ответы [ 2 ]

23 голосов
/ 26 ноября 2008

Если я правильно помню, это известная проблема. Мы повторно создали текстовое поле для включения следующего:

<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>
1 голос
/ 26 ноября 2008

У меня есть ответ на проблему, которая заключается в изменении события нажатия моей кнопки, которое изменяет видимость панелей. Это изменится на что-то вроде этого:

private void Button_Click(object sender, RoutedEventArgs e) {
    if (panel1.Visibility == Visibility.Collapsed) {
        panel1.Visibility = Visibility.Visible;
        DataBoundTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
        panel2.Visibility = Visibility.Collapsed;
    }
    else {
        panel1.Visibility = Visibility.Collapsed;
        DataBoundTextBox.GetBindingExpression(TextBox.TextProperty).UpdateTarget();
        panel2.Visibility = Visibility.Visible;
    }
}

UpdateSource () и UpdateTarget () имеют эффект повторного применения и удаления красного прямоугольника, но это выглядит как уродливый хак Конечно, структура wpf должна скрывать красный прямоугольник для меня, когда содержащая панель свернута. Любое исправление, которое не требует от меня возиться с обязательным выражением, получает мой голос.

Спасибо

Sam

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...