Validation.Error ContentPresenter 更改内容时全部删除

Validation.Error deletes all when ContentPresenter changes content

这是一个 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 只是一个 class,就像这样:

[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 事件来计算有错误的 UI 元素的数量并显示它,以便用户知道哪些选项卡包含验证错误。

一旦我重新 select 原始选项卡(并且 ContentPresenter 显示它),Validation.Error 再次触发(x 次)所以我可以再次获得错误计数。但是当然,另一个选项卡随后会丢失所有错误(事件触发)!

此外,none 的其他选项卡在实际 selected(并且 ContentPresenter 显示它们)之前永远不会获得错误计数。

所以就像验证系统无法识别绑定错误的存在一样,因为那一刻 UI 没有显示,即使 UI 仍然存在。非 selected 选项卡的视觉状态永远不会丢失,因此它们不会被删除和重新创建或类似的东西(它们存储在上面显示的选项卡依赖项 属性 中)。

有没有办法在我的 ContentPresenter 未显示未 select 编辑的选项卡时将它们保留在可视化树中,并最初在可视化树中创建它们?我希望它们都立即可用,这样所有选项卡都可以显示它们的错误计数,并且无论哪个选项卡被 selected 都可以实时更新。

我尝试了一个名为 Gu.Wpf.ValidationScope 的第三方验证库,但它遇到了同样的问题。所以现在我手动使用 Validation.Errors 具有相同的效果。

我放弃了让它与我的自定义控件一起工作的尝试。相反,我发现重新设计 TabControl 和 TabItem 的样式最简单,它们没有这个问题,因为它们的行为类似于 ItemsControl。 TabControl 有很多有用的键盘行为。