Рекомендации по конфигурируемым ресурсам в UserControl? - PullRequest
0 голосов
/ 22 апреля 2019

Я хотел бы услышать несколько советов относительно ресурсов и UserControls ...

Я понял, что UserControls иногда имеет свойства, которые я хочу настроить - но в глобальном масштабе и не для экземпляра .

Позвольте мне привести пример:

Я реализовал UserControl, который в основном представляет собой вкладку (я называю этоRibbonTab):

Пример RibbonTab

Каждая вкладка имеет свой собственный значок и текст (и некоторые другие свойства), которые все DependencyProperties, так что я могу создать экземплярмои вкладки вот так:

<!-- Time Tracking Tab -->
<UserControls:RibbonTab
     Icon="{StaticResource TimeTrackingTabIcon}"
     Text="{StaticResource TimeTrackingTabHeaderString}"
     LabelMode="AutoResize" ResizePriority="0"
     Command="{Binding LoadTimeTrackingViewModelCommand}"/>

<!-- Vacation Tab -->
<UserControls:RibbonTab
     Icon="{StaticResource VacationTabIcon}"
     Text="{StaticResource VacationTabHeaderString}"
     LabelMode="AutoResize" ResizePriority="1"
     Command="{Binding LoadVacationViewModelCommand}"/>

<!-- Payout Tab -->
<UserControls:RibbonTab
     Icon="{StaticResource PayoutTabIcon}"
     Text="{StaticResource PayoutTabHeaderString}"
     LabelMode="AutoResize" ResizePriority="2"
     Command="{Binding LoadPayoutViewModelCommand}"/>

Как видите, цвет фона выбранной вкладки белый.В настоящее время это фиксированное значение в пределах ControlTemplate.Мне бы хотелось, чтобы это настраивалось вместо этого.

Я разобрался с различными возможными решениями, но я не уверен, если я продумал:

1.) Используйте свойство DependencyProperty

Я мог бы представить еще один DependencyProperty, например "SelectedTabColor", и создать вкладки следующим образом:

<!-- Time Tracking Tab -->
<UserControls:RibbonTab
     <!-- All of the previous properties go here... -->
     SelectedTabColor="White"/>

<!-- Vacation Tab -->
<UserControls:RibbonTab
     <!-- All of the previous properties go here... -->
     SelectedTabColor="White"/>

<!-- Payout Tab -->
<UserControls:RibbonTab
     <!-- All of the previous properties go here... -->
     SelectedTabColor="White"/>

Легко видеть, что этот метод требует многократного присоединения значений, новы действительно просто хотите установить это свойство один раз (глобально) и все будет готово.

2.) Используйте ResourceDictionary

Я мог бы сделать UserControl ссылку на StaticResource из приложения ResourceDictionary:

<UserControl x:Class="MyApp.View.UserControls.RibbonTab">
    <Grid>

        <!-- Lots of stuff omitted here... -->

        <Rectangle Fill="{StaticResource RibbonTab_SelectedTabColor}"/>

        <!-- More stuff omitted here... -->

    </Grid>
</UserControl>

Но тогда мой UserControl требует, чтобы приложение / интеграция имели StaticResource, который назван именно так.Перенос UserControl в другой проект был бы кошмаром ...

3.) Использование UserControl.Resources + StaticResources

Другая возможность заключается в использовании Resources атрибут UserControl и поместите его обязательные определения как StaticResources непосредственно там:

<UserControl x:Class="MyApp.View.UserControls.RibbonTab">
    <UserControl.Resources>

        <!--#region Configurable properties -->

        <Color x:Key="SelectedTabColor">White</Color>

        <!--#endregion Configurable properties -->

    </UserControl.Resources>

    <Grid>

        <!-- Lots of stuff omitted here... -->

        <Rectangle Fill="{StaticResource SelectedTabColor}"/>

        <!-- More stuff omitted here... -->

    </Grid>
</UserControl>

Это имеет приятный штрих, поскольку каждый StaticResource хранится вместе с элементом, который фактически использует его, вместоиметь большой ResourceDictionary и потерять отслеживание того, что используется где.

Однако недостатком является то, что вы не можете повторно использовать общее определение (скажем, приложение определяет определенный цвет акцента в его ResourceDictionary) для нескольких UserControls, но приходится переопределять его везде, чтозатрудняет обслуживание.

4.) Используйте UserControl.Resources + ResourceKeys

Лучший подход, который я мог придумать, - определить StaticResources с помощьюResourceKeys (вместо фактических значений) в Resources UserControl.Интегратор должен установить ResourceKeys для существующих ресурсов приложения:

<UserControl x:Class="MyApp.View.UserControls.RibbonTab">
    <UserControl.Resources>

        <!--#region Configurable properties -->
        <!-- Integration hint: Set ResourceKey to your own definition! -->

        <StaticResource x:Key="SelectedTabColor"
             ResourceKey="AppHighlightedElementAccentColor"/>

        <!--#endregion Configurable properties -->

    </UserControl.Resources>

    <Grid>

        <!-- Lots of stuff omitted here... -->

        <Rectangle Fill="{StaticResource SelectedTabColor}"/>

        <!-- More stuff omitted here... -->

    </Grid>
</UserControl>

Я еще не оценил это подробно.Единственный недостаток, который я вижу сейчас, заключается в том, что тип ссылочного ресурса проверяется только во время выполнения, но не во время разработки.


Я упускаю очевидное ...?Есть ли элегантный способ решить эту проблему?Было бы здорово услышать некоторые мнения, потому что сейчас я немного не уверен в том, как поступить ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...