2013-09-22 3 views
4

Я разрабатываю элемент управления WPF, и у меня нет контроля над приложениями, в которых он будет использоваться. Некоторые ключи словаря ресурсов XAML, очевидно, уникальны для моего контроля, например, <Style TargetType="{x:Type MyControl}">, поэтому нет никаких конфликтов.Избегайте конфликтов ключа ресурса XAML в многократно используемых элементах WPF

Однако, мне нужно использовать не уникальные объекты, такие как BooleanToVisibilityConverter. Если я добавлю его с помощью ключа "BooleanToVisibilityConverter", возможно (и, вероятно), что потребитель элемента управления, который включает мой словарь ресурсов, уже определил аналогичный конвертер в своем коде, возможно, с другим поведением.

Стандартные элементы управления как-то избегают конфликтов. Существует <BooleanToVisibilityConverter x:Key="bool2VisibilityConverter" /> в Aero.NormalColor.xaml, который не виден для приложений WPF. Однако я не знаю, как этого добиться.

Как избежать конфликтов имен ресурсов? Как сделать мои имена ресурсов «локальными» для моего контроля?

ответ

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}}" /> 

надеюсь, что это помогает