避免在可重用的WPF控件中出现XAML资源键冲突

5
我正在开发一个WPF控件,但我无法控制它将被使用的应用程序。一些XAML资源字典键明显对于我的控件是唯一的,例如,<Style TargetType="{x:Type MyControl}">,因此不存在冲突的风险。
然而,我还需要使用非唯一对象,比如BooleanToVisibilityConverter。如果我使用"BooleanToVisibilityConverter"键添加它,那么包含我的资源字典的控件的消费者很可能已经在他们的代码中定义了类似的转换器,可能具有不同的行为。
标准控件会以某种方式避免冲突。在Aero.NormalColor.xaml中有一个<BooleanToVisibilityConverter x:Key="bool2VisibilityConverter" />,但它对于WPF应用程序不可见。然而,我不知道如何实现这一点。
如何避免资源名称冲突?如何使我的资源名称对我的控件“本地化”?
2个回答

3
通常情况下,WPF控件的设计方式不需要客户明确包含任何资源字典。具有WPF控件的程序集具有“ThemeInfo”属性:
[assembly: ThemeInfo(
    ResourceDictionaryLocation.None,
    ResourceDictionaryLocation.SourceAssembly
)]

这指定了默认样式的查找位置,而默认样式则写入Themes/Generic.xaml文件。

无论如何,由于资源字典键是一个object,您可以在某个内部静态类中定义绝对唯一的键:

internal static class ResourceKeys
{
    public static readonly object BooleanToVisibilityConverter = new object();
}

使用它们替代字符串在XAML中:

<ResourceDictionary xmlns:local="clr-namespace:YOUR_NAMESPACE_HERE">
    <BooleanToVisibilityConverter x:Key="{x:Static local:ResourceKeys.BooleanToVisibilityConverter}" />
</ResourceDictionary>

1

避免使用键的一种解决方案是,将ValueConverter作为单例使用。

public sealed class SingletonValueConverter : IValueConverter
{
    private static SingletonValueConverter instance;

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static SingletonValueConverter() {
    }

    private SingletonValueConverter() {
    }

    public static SingletonValueConverter Instance {
    get { return instance ?? (instance = new SingletonValueConverter()); }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
        return ...
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
        return ...
    }
}

现在你可以像这样使用ValueConverter
<TextBlock Text="{Binding TestProperty, Converter={x:Static local:SingletonValueConverter.Instance}}" />

希望这有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接