首页 文章

如何在外部库中使用WPF创建动态可更改的样式?

提问于
浏览
1

我正在尝试创建一个库(带有WPF),它将包含一些我的基本模板,用于windows,按钮和一些新的服装控件和模板,供以后在项目中使用 .

我还是WPF的新手 . 我知道我应该在我的外部库中创建一个新的ResourceDictionary,并将所有样式和动态变量放在那里 . 然后在我的主应用程序项目中创建一个MergedResourceDictionary,这将使我可以使用我常用的样式和控件 .

我成功创建了一个基本的实验风格,模板使用两个变量作为DynamicResource,只是为了测试我做了一个 <Brush x:Key="brush_back_standard">RoyalBlue</Brush> . 这用于常规背面着色 . 然后我声明在样式本身动态地使用这个画笔: <Grid Background="{DynamicResource brush_back_standard}"> ,它运作良好 .

当我试图将刷子值更改为运行时时,我的问题就开始了: Style.Resources[ "brush_back_standard" ] = Brushes.Aqua; . 模拟用户稍后在运行时更改应用程序设置中的主题的情况 . 所以这根本不起作用,我得到了例外: ResourceDictionary is read-only and cannot be modified. . 所以如果它对我来说没用,因为用户无法在运行时更改模板 . 我需要找到一些方法让用户在运行时更改窗口模板中的 anything .

完整样式代码(外部库):

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:system="clr-namespace:System;assembly=mscorlib">
<Style x:Key="window_standard"
       TargetType="{x:Type Window}">
    <Style.Resources>
        <system:Double x:Key="thickness_shadow">10</system:Double>
        <Brush x:Key="brush_back_standard">RoyalBlue</Brush>
    </Style.Resources>
    <Setter Property="WindowStyle"
            Value="None" />
    <Setter Property="AllowsTransparency"
            Value="True" />
    <Setter Property="BorderThickness"
            Value="{DynamicResource thickness_shadow}" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Window}">
                <Grid Background="{DynamicResource brush_back_standard}">
                    <AdornerDecorator>
                        <ContentPresenter />
                    </AdornerDecorator>
                    <ResizeGrip x:Name="WindowResizeGrip"
                                HorizontalAlignment="Right"
                                VerticalAlignment="Bottom"
                                Visibility="Collapsed"
                                IsTabStop="false" />
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="ResizeMode"
                             Value="CanResizeWithGrip">
                        <Setter TargetName="WindowResizeGrip"
                                Property="Visibility"
                                Value="Visible" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
        </Setter>
</Style>

访问我的主应用程序项目中的库:

<Application x:Class="diamond.sandbox.executer"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         StartupUri="window_main.xaml">
<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/diamond.core;component/xaml/standard.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

window_main.xaml受到样式的神奇影响:

<Window x:Class="diamond.sandbox.window_main"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="window_main" Height="250" Width="500"
    Style="{DynamicResource window_standard}"
    WindowStartupLocation="CenterScreen"
    Loaded="initialise">

初始化方法(加载window_main后):

private void initialise( object p_sender , RoutedEventArgs p_args )
    {
        Style.Resources[ "brush_back_standard" ] = Brushes.Aqua;
    }

1 回答

  • 3

    好吧,你根本不能修改 Style (甚至不是它的 Resources ),因为它已被冻结 . StyleFreezable ,并且在添加到 ResourceDictionary 时将被WPF冻结 . 相反,你应该只修改 WindowResources

    private void initialise( object p_sender , RoutedEventArgs p_args )
    {
        Resources[ "brush_back_standard" ] = Brushes.Aqua;
    }
    

相关问题