WPF 验证 (IDataErrorInfo) 和选项卡聚焦问题

发布于 2024-08-23 11:58:32 字数 2745 浏览 5 评论 0原文

我有一个 TextBox 绑定到实现 IDataErrorInfo 的对象的属性。 我设置了 TextBoxValidation.ErrorTemplate,它工作正常。问题是我在 TabControl 上有这些,如果我将选项卡更改为另一个选项卡,然后返回到初始选项卡(其中 TextBox 是)。看起来它是经过验证的(就像值是正确的),但实际上并非如此。

这是 IDataErrorInfo 对象 - 请注意,“正确”值是长度为 2 的字符串:

public class Presenter : IDataErrorInfo
{
    public Presenter()
    {
        this.Property = String.Empty;
    }

    public string Property { get; set; }

    public string Error { get { return null; } }

    public string this[string columnName]
    {
        get
        {
             if (columnName == "Property")
             {
                if (this.Property.Length == 2)
                   return null;
                else
                   return "Invalid property length!";
             }
             else return null;
        }
    }
}

这是 XAML:

<TabControl >
    <TabItem Header="tabItem1" Name="tabItem1" GotFocus="tabItem1_GotFocus">
        <Grid>
            <TextBox Width="100" Height="20" x:Name="txtField">
                <TextBox.Style>
                    <Style TargetType="{x:Type TextBox}">
                        <Setter Property="Validation.ErrorTemplate">
                            <Setter.Value>
                            <ControlTemplate>
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition Width="16"/>
                                    </Grid.ColumnDefinitions>
                                    <AdornedElementPlaceholder Grid.Column="0"/>
                                    <Image Source="bullets16.png" Grid.Column="1" ToolTip="{Binding CurrentItem.ErrorContent, Mode=OneWay}">
                                    </Image>
                                </Grid>
                            </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </TextBox.Style>
                <TextBox.Text>
                    <Binding Path="Property" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True">
                    </Binding>
                </TextBox.Text>
            </TextBox>
        </Grid>
    </TabItem>
    <TabItem Header="tabItem2" Name="tabItem2" >
        <Grid />
    </TabItem>
</TabControl>

对我做错了什么有什么想法吗?

I have a TextBox bound to a property of an object which implements IDataErrorInfo.
I set up the Validation.ErrorTemplate of the TextBox, and it works fine. The problem is that I have these on a TabControl, and the validation template doesn't display any more if I change the tab to another one and then come back to the initial tab (where the TextBox is). It looks like it is validated(like the value is correct), but actually it is not.

This is the IDataErrorInfo object - note that a "correct" value is a string with a length of 2:

public class Presenter : IDataErrorInfo
{
    public Presenter()
    {
        this.Property = String.Empty;
    }

    public string Property { get; set; }

    public string Error { get { return null; } }

    public string this[string columnName]
    {
        get
        {
             if (columnName == "Property")
             {
                if (this.Property.Length == 2)
                   return null;
                else
                   return "Invalid property length!";
             }
             else return null;
        }
    }
}

and this is the XAML:

<TabControl >
    <TabItem Header="tabItem1" Name="tabItem1" GotFocus="tabItem1_GotFocus">
        <Grid>
            <TextBox Width="100" Height="20" x:Name="txtField">
                <TextBox.Style>
                    <Style TargetType="{x:Type TextBox}">
                        <Setter Property="Validation.ErrorTemplate">
                            <Setter.Value>
                            <ControlTemplate>
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition Width="16"/>
                                    </Grid.ColumnDefinitions>
                                    <AdornedElementPlaceholder Grid.Column="0"/>
                                    <Image Source="bullets16.png" Grid.Column="1" ToolTip="{Binding CurrentItem.ErrorContent, Mode=OneWay}">
                                    </Image>
                                </Grid>
                            </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </TextBox.Style>
                <TextBox.Text>
                    <Binding Path="Property" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True">
                    </Binding>
                </TextBox.Text>
            </TextBox>
        </Grid>
    </TabItem>
    <TabItem Header="tabItem2" Name="tabItem2" >
        <Grid />
    </TabItem>
</TabControl>

Any ideas on what I am doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

水晶透心 2024-08-30 11:58:32

选项卡项目往往会与装饰器混淆(虽然我不知道为什么,但我经历过)。

我可以重现你的问题。

通过使用 AdornerDecorator 包装 TabItem 的内容来解决此问题。

所以:

<TabControl >
    <TabItem Header="tabItem1" Name="tabItem1" GotFocus="tabItem1_GotFocus">

        <AdornerDecorator>

           <Grid>
           ....
           </Grid>

        </AdornerDecorator>

    </TabItem>
    ...
</TabControl>

Tab items tend to mess up with adorners (although I don't know why, I experienced it).

I could reproduce your problem.

Solve it by wrapping the contents of the TabItem with an AdornerDecorator.

So:

<TabControl >
    <TabItem Header="tabItem1" Name="tabItem1" GotFocus="tabItem1_GotFocus">

        <AdornerDecorator>

           <Grid>
           ....
           </Grid>

        </AdornerDecorator>

    </TabItem>
    ...
</TabControl>
如歌彻婉言 2024-08-30 11:58:32

我遇到的问题是只有第一个(重点)选项卡具有样式,并且只有一个选项卡在更改后仍然存在。这是我最终得到的解决方案(没有 AdornerDecorator

<Style TargetType="{x:Type FrameworkElement}" x:Key="ValidatingControl">
<Style.Triggers>
    <MultiTrigger>
        <MultiTrigger.Conditions>
            <Condition Property="Validation.HasError" Value="True" />
            <Condition Property="IsVisible" Value="True" />
        </MultiTrigger.Conditions>
        <Setter Property="Validation.ErrorTemplate">
            <Setter.Value>
                <ControlTemplate>
                    <DockPanel LastChildFill="True">
                        <Border BorderBrush="Red" BorderThickness="1">
                            <AdornedElementPlaceholder Name="controlWithError"/>
                        </Border>
                    </DockPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="ToolTip" 
        Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors).CurrentItem.ErrorContent}" />
    </MultiTrigger>
</Style.Triggers>

基于这篇文章: http://techqa.info/programming/question/1369643/wpf-error-styles-only-being-rendered-properly-on-visible-tab-of-a- tab-control(不再存在)

I had problem with only first (focused) tab got style and only that one persisted after changing. This is solution I ended up with (without AdornerDecorator)

<Style TargetType="{x:Type FrameworkElement}" x:Key="ValidatingControl">
<Style.Triggers>
    <MultiTrigger>
        <MultiTrigger.Conditions>
            <Condition Property="Validation.HasError" Value="True" />
            <Condition Property="IsVisible" Value="True" />
        </MultiTrigger.Conditions>
        <Setter Property="Validation.ErrorTemplate">
            <Setter.Value>
                <ControlTemplate>
                    <DockPanel LastChildFill="True">
                        <Border BorderBrush="Red" BorderThickness="1">
                            <AdornedElementPlaceholder Name="controlWithError"/>
                        </Border>
                    </DockPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="ToolTip" 
        Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors).CurrentItem.ErrorContent}" />
    </MultiTrigger>
</Style.Triggers>

Based on this article: http://techqa.info/programming/question/1369643/wpf-error-styles-only-being-rendered-properly-on-visible-tab-of-a-tab-control (No longer exists)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文