C# WPF验证(IDataErrorInfo)和标签聚焦问题

C# WPF验证(IDataErrorInfo)和标签聚焦问题,c#,wpf,validation,tabcontrol,idataerrorinfo,C#,Wpf,Validation,Tabcontrol,Idataerrorinfo,我有一个文本框绑定到实现IDataErrorInfo的对象的属性。 我设置了TextBox的Validation.ErrorTemplate,效果很好。问题是,我在选项卡控件上有这些,如果我将选项卡更改为另一个选项卡,然后返回初始选项卡(其中文本框),验证模板将不再显示。看起来它是经过验证的(好像值是正确的),但实际上它不是 这是IDataErrorInfo对象-请注意,“正确”值是长度为2的字符串: public class Presenter : IDataErrorInfo { p

我有一个
文本框
绑定到实现
IDataErrorInfo
的对象的属性。 我设置了
TextBox
Validation.ErrorTemplate
,效果很好。问题是,我在
选项卡控件
上有这些,如果我将选项卡更改为另一个选项卡,然后返回初始选项卡(其中
文本框
),验证模板将不再显示。看起来它是经过验证的(好像值是正确的),但实际上它不是

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


有没有关于我做错了什么的想法?

标签项往往会弄乱装饰物(尽管我不知道为什么,但我经历过)

我可以重现你的问题

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

因此:


....
...

我的问题是,只有第一个(聚焦的)选项卡获得了样式,只有那个选项卡在更改后保持不变。这就是我最终得到的解决方案(没有
AdornerDecorator



(不再存在)

这也是
Expander
内容的一个问题,同样的解决方案也适用。一篇相关的博客文章-不是一个完整的解决方案。初始验证仅适用于第一个选定的选项卡项,其他选项卡项在以后切换到它们时不会自动验证。我发现,通过在OnLoad时在代码中手动设置DataContext,也解决了这个问题,但这很难看。我仍在寻找解决方案…在以.NET 4.5.2为目标,使用
INotifyDataErrorInfo
而不是
IDataErrorInfo
时遇到了这个问题,这个解决方案对我的用例非常有效。@akjoshi的链接已失效。这是它的一个档案:坏链接,转到一个付费网站。当时不是。编辑。
<TabControl >
    <TabItem Header="tabItem1" Name="tabItem1" GotFocus="tabItem1_GotFocus">

        <AdornerDecorator>

           <Grid>
           ....
           </Grid>

        </AdornerDecorator>

    </TabItem>
    ...
</TabControl>
<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>