Validation.Error удаляет все, когда ContentPresenter изменяет содержимое - PullRequest
0 голосов
/ 11 января 2020

Это приложение WPF. Net 4.8. У меня есть элемент управления, похожий на tabcontrol в том, что есть ContentPresenter:

<ContentPresenter Content="{Binding SelectedTab.Content, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" />

Если щелкнуть определенный элемент в списке, содержимое переключается на другой элемент (SelectedTab), содержащийся в свойстве зависимости, которое выглядит как это:

public static readonly DependencyProperty TabsProperty = DependencyProperty.Register(nameof(Tabs), typeof(ObservableCollection<MyTab>), typeof(MyTabLikeControl), new PropertyMetadata(null));

MyTab просто класс, как это:

[ContentProperty(nameof(Content))]
public class MyTab : DependencyObject
{
    #region Title
    public string Title
    {
        get => (string)GetValue(TitleProperty);
        set => SetValue(TitleProperty, value);
    }
    public static readonly DependencyProperty TitleProperty =
        DependencyProperty.Register(nameof(Title), typeof(string), typeof(MyTab), new PropertyMetadata(null));
    #endregion Title

    #region Content
    public object Content
    {
        get => GetValue(ContentProperty);
        set => SetValue(ContentProperty, value);
    }
    public static readonly DependencyProperty ContentProperty =
        DependencyProperty.Register(nameof(Content), typeof(FrameworkElement), typeof(MyTab), new PropertyMetadata(null));
        #endregion Content
}

Вы используете элемент управления, как:

<m:MyTabControl>
    <m:MyTabControl.Tabs>
        <m:MyTab Title="Tab A">
            ...XAML content...
        </m:MyTab>
        <m:MyTab Title="Tab B">
            ...XAML content...
        </m:MyTab>
        <m:MyTab Title="Tab C">
            ...XAML content...
        </m:MyTab>
    <m:MyTabControl.Tabs>
</m:MyTabControl>

Неисправность связана с Проверка. Когда SelectedTab изменяется на один из других элементов в коллекции Tabs, Validation.Error запускается (x раз), удаляя все ошибки проверки (используя IDataErrorInfo) на вкладке, которую мы покидаем. Это ПЛОХО, потому что я использую событие Validation.Error, чтобы подсчитать количество элементов пользовательского интерфейса с ошибками и отобразить его, чтобы пользователь знал, какие вкладки содержат ошибки проверки.

После повторного выбора исходной вкладки (и ContentPresenter отображает его), Validation.Error запускается снова (x раз), поэтому я могу снова получить счетчик ошибок. Но, конечно, другая вкладка теряет все свои ошибки (событие срабатывает)!

Более того, ни одна из других вкладок никогда не получит счетчик ошибок до тех пор, пока они фактически не будут выбраны (а ContentPresenter отобразит их).

Таким образом, система проверки не распознает существование ошибки привязки, потому что этот интерфейс не отображается в этот момент, даже если он все еще существует. Визуальное состояние невыбранных вкладок никогда не теряется, поэтому они не удаляются и не воссоздаются или что-то в этом роде (они хранятся в свойстве зависимостей вкладок, показанном выше).

Возможно, есть способ сохранить невыбранные вкладки в визуальном дереве, когда они не отображаются моим ContentPresenter, и изначально создавать их в визуальном дереве? Я хочу, чтобы все они были доступны немедленно, чтобы все вкладки могли отображать количество ошибок и обновляться в реальном времени независимо от того, какая вкладка выбрана.

Я попробовал стороннюю библиотеку проверки с именем Gu.Wpf.ValidationScope, но она пострадала одинаково проблема. Так что теперь я использую Validation.Errors вручную с тем же эффектом.

1 Ответ

0 голосов
/ 14 января 2020

Я бросил попытки заставить это работать с моим пользовательским контролем. Вместо этого я обнаружил, что проще всего переустановить TabControl и TabItem, у которых нет этой проблемы, потому что они действуют как ItemsControl. В любом случае, у TabControl много полезного поведения клавиатуры.

...