Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用于Validation.ErrorTemplate的Wpf动态资源查找_C#_Wpf_Resourcedictionary_Dynamicresource - Fatal编程技术网

C# 用于Validation.ErrorTemplate的Wpf动态资源查找

C# 用于Validation.ErrorTemplate的Wpf动态资源查找,c#,wpf,resourcedictionary,dynamicresource,C#,Wpf,Resourcedictionary,Dynamicresource,在我的App.xaml中,我为Validation.ErrorTemplate定义了一个资源,它依赖于动态BorderBrush资源。我打算在我拥有的每个窗口以及窗口内的不同块中定义唯一的BorderBrush <!--validation error template--> <ControlTemplate x:Key="NonValid"> <Border BorderBrush="{DynamicResource BorderBrush}" Borde

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

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

我应该怎么做才能使文本框周围有红色的边框?

您看到的行为非常好。其背后的理由:

Validation.ErrorTemplate
位于窗口的
装饰层
,该装饰层位于窗口中所有其他控件的上方。这就是为什么它不能看到在网格级别定义的资源,不能用窗口资源解析引用


如果您想动态地解决它,唯一可能的解决方案是在窗口资源中声明它或使用静态分配。

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

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();
    }
}
公共类ResourceProviderConverter:IValueConverter
{
/// 
///从元素可视化树返回请求的资源
/// 
///应包含可访问资源的FrameworkElement
/// 
///资源密钥
/// 
///如果找到资源,则返回资源值
公共对象转换(对象值、类型targetType、对象参数、CultureInfo区域性)
{            
if(参数!=null&&(值为FrameworkElement))
{
var result=element.TryFindResource(参数);
如果(结果!=null)
返回结果;
}
不做任何事;
}
公共对象转换回(对象值、类型targetType、对象参数、CultureInfo区域性)
{
抛出新的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中的更改。但与DynamicSource不同,它不会立即发生。通过绑定解析的静态资源允许每个实例进行自定义。

我的主要目的是分别对
ErrorTemplate
s进行参数化。我试图使用本地资源来实现这一点,但忘记了装饰器行为。谢谢你的澄清
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>