我正在尝试制作一个库(使用WPF),其中将包含我的一些窗口、按钮的基本模板,以及一些其他新的服装控件和模板,以便稍后在项目中使用。
我还是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.
。因此,如果它真的是只读的,那么它对我来说有点无用,因为用户无法在运行时更改模板。我需要找到一些方法,让用户在运行时更改窗口模板中的任何内容。
完整样式代码(外部库):
<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;
}
好吧,你根本不能修改Style
(甚至不能修改它的Resources
),因为它已经被冻结了。Style
是Freezable
,当添加到ResourceDictionary
时将被WPF冻结。相反,您应该只修改Window
的Resources
:
private void initialise( object p_sender , RoutedEventArgs p_args )
{
Resources[ "brush_back_standard" ] = Brushes.Aqua;
}