展开时未显示WPF扩展器验证错误

时间:2012-06-11 10:16:54

标签: wpf validation mvvm expander idataerrorinfo

使用MVVM。我有一个DataTemplate,用于显示每个对象中有一些控件的扩展器。

<DataTemplate>
    <Expander ExpandDirection="Down" IsExpanded="False">
        <Expander.Header>
            <TextBlock>
                <TextBlock.Text>
                    <MultiBinding StringFormat="Platform Group {0} {1}">
                        <Binding Path="PlatformGroupCode"/>
                        <Binding Path="PlatformGroupName"/>
                    </MultiBinding>
                </TextBlock.Text>
            </TextBlock>
        </Expander.Header>
        <vw:PlatformGroup HorizontalAlignment="Left"/>
    </Expander>
</DataTemplate>

在该视图中,有两个文本框绑定到这两个属性。我在我的VM中使用IDataErrorInfo进行验证,我在主应用程序资源中使用了一种样式,将错误消息显示为工具提示:

<Style TargetType="{x:Type TextBox}">
    <Style.Triggers>
        <Trigger Property="Validation.HasError" Value="true">
            <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self},Path=(Validation.Errors).CurrentItem.ErrorContent}"/>
        </Trigger>
    </Style.Triggers>
</Style>

当添加新组时,2个属性具有默认值,这是无效的,因此我希望文本框为红色以提示用户输入数据。如果Expander的IsExpanded设置为true,则此方法有效。但如果它是假的,我必须扩展并更改其中一个文本框中的值,以便显示红色边框和工具提示。

我不想将扩展器设置为扩展,因为最终会有很多控件。扩展器扩展后如何才能显示红色边框?更好的是,是否有一种方法可以扩展新添加的扩展器(当用户添加新组时,我将PlatformGroupviewModel添加到PlatformGroupviewModel的observablecollection)?

编辑更多细节: 顶级视图:

 <StackPanel Orientation="Vertical">
        <ScrollViewer VerticalScrollBarVisibility="Auto" MaxHeight="630">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="5*" />
                    <ColumnDefinition Width="5*" />
                </Grid.ColumnDefinitions>
                <StackPanel Orientation="Vertical" Grid.ColumnSpan="2" Grid.Row="1" HorizontalAlignment="Stretch">
                    <Expander ExpandDirection="Down" IsExpanded="True" Header="Header" HorizontalAlignment="Stretch" Name="expHeader" VerticalAlignment="Top">
                        <vw:Header DataContext="{Binding HeaderVM}"/>
                    </Expander>
                    <Expander ExpandDirection="Down" IsExpanded="True" Header="Platform Groups" HorizontalAlignment="Stretch" Name="expPlatformGroups" VerticalAlignment="Top">
                        <AdornerDecorator>
                            <vw:PlatformGroups DataContext="{Binding PlatformGroupsVM}"/>
                        </AdornerDecorator>
                    </Expander>
                </StackPanel>
            </Grid>
        </ScrollViewer>
</StackPanel>

PlatformGroups视图:

 <StackPanel Orientation="Vertical" HorizontalAlignment="Stretch" Margin="10,10,10,10">
    <StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch" Margin="0,10">
        <Label Content="Number of platform groups" VerticalAlignment="Center"/>
        <vw:IntegerInput MinValue="0" MaxValue="50" MaxLength="2"  Text="{Binding Path=NumPlatformGroups, Mode=TwoWay,ValidatesOnDataErrors=True}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
    </StackPanel>
    <ItemsControl IsTabStop="False" ItemsSource="{Binding PlatformGroups}" Margin="20,10" VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <VirtualizingStackPanel />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Expander ExpandDirection="Down" IsExpanded="False">
                    <Expander.Header>
                        <TextBlock>
                            <TextBlock.Text>
                                <MultiBinding StringFormat="Platform Group {0} {1}">
                                    <Binding Path="PlatformGroupCode"/>
                                    <Binding Path="PlatformGroupName"/>
                                </MultiBinding>
                            </TextBlock.Text>
                        </TextBlock>
                    </Expander.Header>
                    <AdornerDecorator>
                        <vw:PlatformGroup HorizontalAlignment="Left"/>
                    </AdornerDecorator>
                </Expander>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
        <ItemsControl.Template>
            <ControlTemplate>
                <Border BorderThickness="{TemplateBinding Border.BorderThickness}" Padding="{TemplateBinding Control.Padding}"
        BorderBrush="{TemplateBinding Border.BorderBrush}" Background="{TemplateBinding Panel.Background}" SnapsToDevicePixels="True">
                    <ScrollViewer VerticalScrollBarVisibility="Auto" MaxHeight="400" CanContentScroll="True" Padding="{TemplateBinding Control.Padding}" Focusable="False">
                        <ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
                    </ScrollViewer>
                </Border>
            </ControlTemplate>
        </ItemsControl.Template>
    </ItemsControl>
</StackPanel>

1 个答案:

答案 0 :(得分:3)

根据this帖子,将Expander内容封装在AdornerDecorator内可以解决此问题 -

<DataTemplate>
    <Expander ExpandDirection="Down" IsExpanded="False">
        <Expander.Header>
           ...
        </Expander.Header>

        <AdornerDecorator>
            <vw:PlatformGroup HorizontalAlignment="Left"/>
        </AdornerDecorator>

    </Expander>
</DataTemplate>

另一个SO线程确认了这一点 - Issue with WPF validation(IDataErrorInfo) and tab focusing

此连接错误中还提到了其他一些WorkArounds -

TabControl doesn't display Validation error information correctly when switching tabs back and forth