2

我目前正在使用 WPF 验证开发 MVVM 解决方案。

我想做的是能够在我的上下文中使用“ShowErrors”可见性属性来控制何时显示验证装饰器。

我的 Application.xaml 文件中包含 WPF 组合框验证装饰器的以下模板;

<Style TargetType="{x:Type ComboBox}">
            <Setter Property="VerticalAlignment" Value="Center" />
            <Setter Property="Margin" Value="0,2,40,2" />
            <Setter Property="Validation.ErrorTemplate">
                <Setter.Value>
                    <ControlTemplate>
                        <DockPanel LastChildFill="true">
                            <Border Background="Red" DockPanel.Dock="right" Margin="5,0,0,0" Width="20" Height="20" CornerRadius="10"
                            ToolTip="{Binding ElementName=customAdorner1, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
                                <TextBlock Text="!" VerticalAlignment="center" HorizontalAlignment="center" FontWeight="Bold" Foreground="white">
                                </TextBlock>
                            </Border>
                            <AdornedElementPlaceholder Name="customAdorner1" VerticalAlignment="Center" >
                                <Border BorderBrush="red" BorderThickness="1" />
                            </AdornedElementPlaceholder>
                        </DockPanel>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

(我有一个单独的文本框模板)

在 StackOverflow 和 Google 上进行了一些搜索后,我尝试将以下内容添加到 DockPanel;

Visibility="{Binding DataContext.ShowErrors, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Mode=TwoWay}"

但这似乎对我不起作用,即使相同的方法在 Main XAML 中也能正常工作......有什么想法吗?

编辑:我将 DataContext 绑定到的 UserControl 的 x:Name 为“MainContext”

我发现了一些建议;

Visibility="{Binding DataContext.ShowErrors, Source={x:Reference Name=MainContext}, Mode=TwoWay}">

这给出了一个错误

未解决的参考'MainContext'

也;

Visibility="{Binding DataContext.ShowErrors, ElementName=MainContext, Mode=TwoWay}">

这只是行不通。

Edit2:如果我将整个装饰器移出 Appliation.xaml 并移入 UserControl 资源,则使用;

Visibility="{Binding DataContext.ShowErrors, ElementName=MainContext, Mode=TwoWay}">

它有效......虽然不理想,因为我不想在所有屏幕上重复模板

编辑3:好的,所以我现在找到了解决方法。我将以下内容用于可见性绑定...

Visibility="{Binding ElementName=customAdorner1, Path=AdornedElement.Parent.DataContext.ShowErrors, Converter={StaticResource MyBolVisibilityConverter}, Mode=TwoWay}"

然后,我在上下文中添加了一个 Boolean ShowErrors 属性,并添加了一个 Converter 以将 Boolean 值转换为 Visibility 值,主要是因为 ShowErrors 属性实际结束的位置。

这有点令人困惑,因为我的表单是一个主详细信息安排,其中装饰器显示在详细信息部分中,它有自己的数据上下文。当然,这不能直接访问 UserControl 的 DataContext。

这对我来说真的有点像黑客,所以我希望有更好的解决方案!

4

1 回答 1

2

我通过向我的 DataContext 添加一个ShowErrors布尔属性来解决这个问题,然后将 Adorner Visibility 绑定到 AdornedElement 的父母 DataContext,当然如果我知道 DataContext。

我在 Application.xaml 文件中使用了以下 XAML;

<Converters:BolVisibilityConverter x:Key="MyBolVisibilityConverter"/>
<Style TargetType="{x:Type TextBox}">
      <Setter Property="VerticalAlignment" Value="Center" />
      <Setter Property="Margin" Value="0,2,40,2" />
      <Setter Property="Validation.ErrorTemplate">
          <Setter.Value>
              <ControlTemplate>
                        <DockPanel LastChildFill="true" Visibility="{Binding ElementName=customAdorner, Path=AdornedElement.Parent.DataContext.ShowErrors, Converter={StaticResource MyBolVisibilityConverter}, Mode=TwoWay}">
                            <Border Background="Red" DockPanel.Dock="right" Margin="5,0,0,0" Width="20" Height="20" CornerRadius="10"
                            ToolTip="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
                                <TextBlock Text="!" VerticalAlignment="center" HorizontalAlignment="center" FontWeight="Bold" Foreground="white">
                                </TextBlock>
                          </Border>
                          <AdornedElementPlaceholder Name="customAdorner" VerticalAlignment="Center" >
                         <Border BorderBrush="red" BorderThickness="1" />
                       </AdornedElementPlaceholder>
                   </DockPanel>
               </ControlTemplate>
           </Setter.Value>
      </Setter>
</Style>

我使用了以下转换器代码;

Namespace Converters

    Public Class BolVisibilityConverter
        Implements IValueConverter

        Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As Globalization.CultureInfo) As Object Implements IValueConverter.Convert

            If value Is Nothing OrElse value = False Then

                Return Visibility.Hidden

            Else

                Return Visibility.Visible

            End If

        End Function

        Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As Globalization.CultureInfo) As Object Implements IValueConverter.ConvertBack
            Return DirectCast(value, Boolean)

        End Function
    End Class

End Namespace

然后,我只需将 DataContext 中的 ShowErrors 属性设置为 True 或 False 以显示或隐藏装饰器。

这非常有用,因为装饰器总是出现在最顶层,因此显示在自定义对话框等的顶部。

于 2013-02-03T22:10:02.243 回答