Validation.ErrorTemplate 的 Wpf 动态资源查找 [英] Wpf dynamic resource lookup for Validation.ErrorTemplate

查看:60
本文介绍了Validation.ErrorTemplate 的 Wpf 动态资源查找的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的 App.xaml 中,我为 Validation.ErrorTemplate 定义了一个资源,它依赖于动态 BorderBrush 资源.我打算在我拥有的每个窗口以及窗口内的不同块中定义唯一的 BorderBrush.

in my App.xaml I defined a resource for Validation.ErrorTemplate, which depends on dynamic BorderBrush resource. I intend to define unique BorderBrush in each window I have and also within different blocks inside window.

<!--validation error template-->
<ControlTemplate x:Key="NonValid">
    <Border BorderBrush="{DynamicResource BorderBrush}" BorderThickness="2" Margin="5">
        <AdornedElementPlaceholder x:Name="ui"/>
    </Border>
</ControlTemplate>

这个用来演示我的问题(也有动态画笔资源)

and this one to demonstrate my problem (also with dynamic brush resource)

<!--test template-->
<ControlTemplate x:Key="ButtonRes" TargetType="Button">
    <Border BorderBrush="{DynamicResource BorderBrush}" BorderThickness="2" Background="Khaki">
        <ContentPresenter />
    </Border>
</ControlTemplate>

现在我使用这些模板的窗口可以解析普通模板的刷资源,但不能解析Validation.ErrorTemplate

and now window, where I use these templates, can resolve brush resource for normal template, but not for Validation.ErrorTemplate!

<Window x:Class="MyApp.MyWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Test" Height="300" Width="300">
    <Window.Resources>
        <!-- window overrides resource-->
        <SolidColorBrush x:Key="BorderBrush" Color="Blue"/>
    </Window.Resources>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <!-- button can see window resource-->
        <Button Template="{StaticResource ButtonRes}"/>        

        <Grid Grid.Row="1">
            <Grid.Resources>
                <!-- grid overrides resource-->
                <SolidColorBrush x:Key="BorderBrush" Color="Red"/>
            </Grid.Resources>

            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition/>
            </Grid.RowDefinitions>

            <!-- button can see grid resource-->
            <Button Template="{StaticResource ButtonRes}"/>

            <!-- errorTemplate CAN     SEE window resource-->
            <!-- errorTemplate CAN NOT SEE grid   resource-->
            <TextBox Grid.Row="1" VerticalAlignment="Center" Text="{Binding Name}" 
                 Validation.ErrorTemplate="{StaticResource NonValid}"/>
        </Grid>
    </Grid>
</Window>

我应该怎么做才能在 TextBox 周围获得 RED 边框?

what should I do to get RED border around TextBox?

推荐答案

我已经实现了一个绑定转换器,它可以从 Validation.ErrorTemplate 中找到资源.它需要一个 FrameworkElement 实例(显示 ErrorTemplate 的元素)和资源键:

I have implemented a binding converter which can find resources from Validation.ErrorTemplate. It needs an instance of FrameworkElement (element which shows ErrorTemplate) and resource key:

public class ResourceProviderConverter : IValueConverter
{
    /// <summary>
    /// Returns requested resource from element visual tree
    /// </summary>
    /// <param name="value">Should contain FrameworkElement which has access to resource</param>
    /// <param name="targetType"></param>
    /// <param name="parameter">Resource key</param>
    /// <param name="culture"></param>
    /// <returns>Resource value if resource was found</returns>
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {            
        if (parameter != null && (value is FrameworkElement element))
        {
            var result = element.TryFindResource(parameter);
            if (result != null)
                return result;
        }

        return Binding.DoNothing;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

修改的错误模板:

<local:ResourceProviderConverter x:Key="ResourceProvider"/>

<ControlTemplate x:Key="NonValid">
    <Border BorderBrush="{Binding ElementName=ui, Path=AdornedElement, 
                                  Converter={StaticResource ResourceProvider}, 
                                  ConverterParameter='BorderBrush', 
                                  FallbackValue={x:Static Brushes.Purple}}" 
            BorderThickness="2" Margin="5">
        <AdornedElementPlaceholder x:Name="ui"/>
    </Border>
</ControlTemplate>

每次显示 ErrorTemplate 时都会触发绑定和转换器.因此可以更新资源并查看 ErrorTemplate 中的更改.但与 DynamicResource 不同的是,它不会立即发生.通过绑定解析的静态资源允许按实例自定义.

Binding and therefore converter are triggered every time when ErrorTemplate is shown. So it is possible to update resources and see changes in ErrorTemplate. But unlike DynamicResource it doesn't happen immediately. Still resource which is resolved by binding allows customization per instance.

这篇关于Validation.ErrorTemplate 的 Wpf 动态资源查找的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆