C# 用于Validation.ErrorTemplate的Wpf动态资源查找
在我的App.xaml中,我为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
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>