首页 > 解决方案 > 关于 UserControl 中可配置资源的建议?

问题描述

我想听听一些关于资源和UserControls...的建议

我意识到UserControls有时有我希望可配置的属性 - 但在全球范围内不是 per-instance

让我给你举个例子:

我已经实现了一个UserControl基本上代表一个选项卡的(我称之为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.) 使用资源字典

我可以从应用程序中UserControl引用:StaticResourceResourceDictionary

<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哪里使用的东西进行大而丢失的跟踪。

但是,缺点是您不能在多个 中重用一个通用定义(假设应用程序在其 中定义了某种强调色ResourceDictionaryUserControls,而必须在任何地方重新定义它,这使得它难以维护。

4.) 使用 UserControl.Resources + ResourceKeys

到目前为止,我能想到的最好StaticResources方法是ResourceKeys在. 集成商必须将 设置为应用程序的现有资源:ResourcesUserControlResourceKeys

<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>

我还没有详细评估这一点。我现在可以看到的唯一缺点是仅在运行时检查引用资源的类型,而不是在设计时检查。


我错过了明显的......?有没有一种优雅的方法来解决这个问题?很高兴听到一些意见,因为现在我有点不确定如何进行......

标签: c#wpf

解决方案


推荐阅读