我在WPF应用程序的单独dll中有一个BaseSkin和多个UserSkins.
根据使用应用程序的用户,基础外观和其中一个用户外观将合并到资源字典中并加载以供应用程序使用.
我的目标是能够在BaseSkin文件中指定样式,然后在特定的UserSkin文件上能够覆盖它,更改我需要的任何属性.
我知道我可以通过使用这样的BasedOn属性来实现这一点:
<Style x:Key="ButtonBg" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Green"/>
</Style>
Run Code Online (Sandbox Code Playgroud)
<Style x:Key="CustomButtonBg" TargetType="{x:Type Button}" BasedOn="{StaticResource ButtonBg}">
<Setter Property="Background" Value="Blue"/>
</Style>
Run Code Online (Sandbox Code Playgroud)
问题是现在元素必须具有StyleButtonBg样式,实际上可能无法实现.有没有办法让两个样式使用相同的键(ButtonBg),并且当它们合并时,应用程序在User用户中查找名为ButtonBg的样式,如果不存在,请使用base中的样式?
我想如果我可以将BasedOn属性中的程序集名称指向BaseSkin文件,当我给它们相同的密钥时,我可以避免命名错误,但我找不到任何方法来做到这一点.其他选项只是强制执行每个样式,即使没有任何变化,或者在皮肤中以编程方式检查,但这些是最后的度假胜地.
正如我读到的:http://msdn.microsoft.com/en-us/library/cc903952(VS.95).aspx,特别是标有"使用ResourceDictionary的前向引用"的部分:
来自任何给定资源字典的静态资源引用必须引用已在资源引用之前以词法方式定义的资源.静态资源引用无法解析转发引用.因此,如果使用静态资源引用,则必须设计资源字典结构,以便在每个相应资源字典的开头或附近定义用于进一步按资源使用的资源.
这是否意味着我无法在App.xaml中执行此类操作:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Assets/Colors.xaml"/>
<ResourceDictionary Source="Assets/Brushes.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Run Code Online (Sandbox Code Playgroud)
其中Brushes.xaml包含SolidColorBrush,LinearColorBrush等,引用Colors.xaml中定义的颜色的定义?
例如
<SolidColorBrush x:Key="OrangeRedBrush" Color="{StaticResource AppOrangeRed}"/>
Run Code Online (Sandbox Code Playgroud)
?
我在Colors.xaml中定义我的颜色,如:
<Color x:Key="AppOrangeRed">#FFBF3C1F</Color>
Run Code Online (Sandbox Code Playgroud)
我收到一个运行时错误,指出它无法找到具有键'AppOrangeRed'的资源.
组织颜色和画笔的最佳实践是什么,以便可以重复使用(在适当的情况下,我理解颜色是结构和画笔是参考对象,在http://weblogs.manas.com.ar/spalladino/2009/中解释03/02/silverlight-xaml-guidelines /)
谢谢Rob
我正在尝试将wpf资源字典合并到后面的代码上,但是为了解决这个问题,这是行不通的.如果我尝试合并文档本身的字典,它正在运行,例如:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication212;assembly=WpfApplication212">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Theme.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="{x:Type local:URComboBox}" BasedOn="{StaticResource ComboBoxStyle}">
</Style>
Run Code Online (Sandbox Code Playgroud)
这是有效的,但如果我评论ResourceDictionary.MergedDictionaries并在代码中尝试这样:
ResourceDictionary skin = new ResourceDictionary();
skin.Source = styleLocation;
ResourceDictionary skinFather = new ResourceDictionary();
skinFather.MergedDictionaries.Add(skin);
skinFather.Source = styleLocationFather;
Run Code Online (Sandbox Code Playgroud)
这会因为无法找到资源而中断.
我正在尝试创建一个应用选项卡,其中每个选项卡都有一个按钮区域和一个视图区域.
现在每个选项卡在布局中基本上具有相同的布局,我希望能够重用相同的布局,这样我就不必在很多地方进行更改(这只是不好的编程).我可以使用资源或样式完成此操作.
如果可能,请提供灯光代码示例.
编辑:我已经决定添加一个我正在尝试做的例子,因为我还没有得到它.
在每个TabItem下我试图重新创建这个网格(它有点复杂,但你明白了):
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="200"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border Margin="10"
BorderBrush="{StaticResource MediumColorBrush}"
CornerRadius="10"
BorderThickness="2"
Grid.Row="0">
<!-- First content goes here -->
</Border>
<Border Margin="10"
BorderBrush="{StaticResource MediumColorBrush}"
CornerRadius="10"
BorderThickness="2"
Grid.Row="1">
<!-- Second content goes here -->
</Border>
</Grid>
Run Code Online (Sandbox Code Playgroud)
你也可以看到2个边框是一样的.现在我需要将一些内容占位符放在我的评论所在的位置.我不想在资源字典中声明这个Grid布局,然后在我使用它的地方将单独的内容放入每个边框.
我可能有很多TabItems,所以重复这段代码不是一个好主意,每个Tab页面将在2个占位符中有不同的内容.
我可以用了
<ContentPresenter Content="{Binding}" />
Run Code Online (Sandbox Code Playgroud)
只有1个内容的东西,当会有更多内容时会发生什么.
我有一个WPF应用程序,如果我在Visual Studio中调试(F5)(调试和发布模式都工作),可以很好地工作,但如果我尝试双击bin\Release文件夹中的.exe,Windows会杀死应用程序立即.
问题似乎是可执行文件找不到"PresentationFramework.Aero",我将其添加到我的App的资源字典中,如下所示:
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary
Source="/PresentationFramework.Aero;component/themes/Aero.NormalColor.xaml" />
<ResourceDictionary
Source="pack://application:,,,/WPFToolkit;component/Themes/Aero.NormalColor.xaml" />
</ResourceDictionary.MergedDictionaries>
Run Code Online (Sandbox Code Playgroud)
包含Aero主题(或指向它)的正确方法是什么,以便我可以发布我的应用程序?
这是我得到的确切错误:
无法加载文件或程序集"PresentationFramework.Aero,Culture = neutral"或其依赖项之一.系统找不到指定的文件.":"PresentationFramework.Aero,Culture = neutral
是否可以在样式中定义ResourceDictionary?
例如,假设我想为StackPanels设置两种不同的样式,并且在一种情况下,我希望所有按钮都是蓝色,另一种我希望它们是红色.这可能吗?
就像是
<Style x:Key="RedButtonsPanel" TargetType="{x:Type StackPanel}">
<Setter Property="Orientation" Value="Horizontal" />
<Setter Property="StackPanel.Resources">
<Setter.Value>
<ResourceDictionary>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Red" />
</Style>
</ResourceDictionary>
</Setter.Value>
</Setter>
</Style>
Run Code Online (Sandbox Code Playgroud)
上面的代码失败了,关于Setter的Property值的错误不能为null(即使它显然不是null).
我可以做点什么
<ResourceDictionary x:Key="RedButtons">
<Style TargetType="{x:Type Button}">
<Setter Property="Width" Value="100" />
<Setter Property="Background" Value="Red" />
</Style>
</ResourceDictionary>
<StackPanel Resources={StaticResource RedButtons} />
Run Code Online (Sandbox Code Playgroud)
但是我想知道是否有办法将ResourceDictionary合并到样式中.
我似乎无法为我的应用程序中的所有窗口设置默认背景颜色.有谁知道如何做到这一点?
目前我正在我的App.xaml文件中设置一个主题.
<Application>
<Application.Resources>
<ResourceDictionary Source="Themes/SomeTheme.xaml" />
Run Code Online (Sandbox Code Playgroud)
这基本上是整个应用程序的样式
在SomeTheme.xaml我的内部尝试为我的所有窗口设置默认颜色.
<SolidColorBrush Color="{DynamicResource MainColor}" x:Key="CommonBackgroundBrush" />
<Style TargetType="{x:Type Window}">
<Setter Property="Background" Value="{DynamicResource CommonBackgroundBrush}" />
</Style>
Run Code Online (Sandbox Code Playgroud)
对于类型的导数,此语法完全被忽略Window.
有没有办法强制风格适用于所有衍生品Window?
这种语法的奇怪之处在于它实际上在VS设计预览窗口中显示了正确的颜色.
如果我有这些词典:
dict1.xaml:
<Color x:Key="Color1">Red</Color>
dict2.xaml:
<SolidColorBrush x:Key="Brush1" Color={StaticResource Color1} />
这有效:
App.xaml中:
<MergedDictionaries>
<ResourceDictionary Source="dict1.xaml"/>
<MergedDictionaries>
Run Code Online (Sandbox Code Playgroud)
SomePage.xaml:
<UserControl.Resources>
<MergedDictionaries>
<ResourceDictionary Source="dict2.xaml"/>
</MergedDictionaries>
</UserControl.Resources>
Run Code Online (Sandbox Code Playgroud)
这不是:
App.xaml在应用程序级别合并.
我收到有关未找到Color1的错误.
为什么是这样 ?/它有办法解决吗?我知道这个例子很简单,但真正的例子太长了.基本上我只是想在不同的文件中组织我的样式和模板:
编辑:奇怪的是,如果我在代码中执行此操作Application_Startup,在设置RootVisual属性之前,我没有收到错误...我只是为什么感到困惑!
只是想问一个关于人们用于"资源字典(WPF)"项目的命名约定的一般性问题.
在我继承的项目中,我有各种各样的命名约定的资源字典.因此,我正在寻找管理资源词典的建议.
请从任何答案中排除Themes文件夹和那些资源词典.
我有一个Button控件作为资源字典中的资源,如下所示:
<!--ButtonResources.xaml file-->
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Button x:Key="buttonResource" Content={Binding BoundText}/>
</ResourceDictionary>
<!--ButtonResources.xaml file-->
Run Code Online (Sandbox Code Playgroud)
我现在用这以上按钮控制绑定到ContentControl中控制的内容属性在2个不同的视窗的.xaml文件,其中每个Window都有自己的DataContext,从而每一个窗口应该显示Content基于其上述按钮控制的ViewModel's BoundText属性值,如下对每个窗口.
<Window x:Class="TestClass1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ButtonResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<ContentControl Content={StaticResource buttonResource}/>
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
但是,问题是两个Window都显示了BoundText属性的相同值,这意味着两个WPF Windows都具有来自资源的相同按钮控制实例,在Windows中都使用.
如何解决此问题,以便每个窗口从资源获取单独的按钮控件,并仍然从他们自己的ViewModel显示属性的不同值?BoundText
编辑:
由于下面提到的原因MSDN,我不能使用x:Shared ="False"属性来解决此问题:
•包含项的ResourceDictionary不得嵌套在另一个ResourceDictionary中.例如,对于已经是ResourceDictionary项的Style内的ResourceDictionary中的项,您不能使用x:Shared.