我有一个简单的WPF窗口,上面有12个按钮.我希望将相同的样式应用于所有这些样式.此代码产生相同的错误:
<Window x:Class="TestApp.TestWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TestWindow" Height="400" Width="500"
WindowStyle="None" WindowState="Maximized">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/AllResources.xaml"/>
<ResourceDictionary>
<Style TargetType="{x:Type Button}">
<Setter Property="FontSize" Value="100"/>
</Style>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Content="1" Name="Button1"/>
<Button Grid.Column="1" Content="2" Name="Button2"/>
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
第一个按钮没有应用它的样式,但第二个按钮没有.我可以设置一个键并在每个按钮上使用它,但我更愿意让WPF为我处理.我在写这篇文章时发现,当我不包含外部ResourceDictionary时,它按预期工作.这将是一个问题,因为我的应用程序扩展,因为我有多个需要共享相同资源的窗口.修改后的代码如下:
<Window x:Class="TestApp.TestWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TestWindow" Height="400" Width="500"
WindowStyle="None" WindowState="Maximized">
<Window.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="FontSize" Value="100"/>
</Style>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Content="1" Name="Button1"/>
<Button Grid.Column="1" Content="2" Name="Button2"/>
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
如果我(而不是删除合并的词典)添加x:Key ="key"属性,然后将该样式显式分配给每个按钮,它也可以工作. …
我创建了一个类库,它包含WPF Windows和一些从我的c#类继承的用户控件,可以帮助我自定义某些wpf控件.
现在我想添加ResourceDictionary,以帮助我在我的wpf类之间共享样式.可能吗?
谢谢.
编辑:位于MY.WpfPresentation.Main项目中的资源字典文件(名为Styles.xaml):
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxgt="http://schemas.devexpress.com/winfx/2008/xaml/grid/themekeys"
xmlns:MYNetMisc="clr-namespace:MY.Net.Misc;assembly=MY.Net"
>
<Style x:Key="customRowStyle" BasedOn="{StaticResource {dxgt:GridRowThemeKey ResourceKey=RowStyle}}" TargetType="{x:Type dxg:GridRowContent}">
<Setter Property="Foreground" Value="{Binding Path=DataContext.balance, Converter={MYNetMisc:BalanceToColor OnlyNegative=false}}" />
</Style>
</ResourceDictionary>
Run Code Online (Sandbox Code Playgroud)
使用它:
<MYNetPresentation:frmDockBase.Resources>
<ResourceDictionary x:Key="style">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MY.WpfPresentation.Main;component/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
<DataTemplate x:Key="TabTemplate">
<dxlc:LayoutControl Padding="0" ScrollBars="None" Background="Transparent">
<Image Source="/Images/Icons/table-32x32.png" Width="12" Height="12" />
<TextBlock Text="{Binding}" HorizontalAlignment="Left" VerticalAlignment="Center" />
</dxlc:LayoutControl>
</DataTemplate>
</MYNetPresentation:frmDockBase.Resources>
Run Code Online (Sandbox Code Playgroud) 我似乎无法将合并的字典添加到XAML中的合并字典集合中.
Theme.xaml
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Mine;component/Themes/Palette.Blue.xaml"/>
<ResourceDictionary Source="/Mine;component/Themes/Template.xaml"/>
</ResourceDictionary.MergedDictionaries>
Run Code Online (Sandbox Code Playgroud)
应用资源
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Mine;component/Themes/Theme.xaml"/>
<!--
<ResourceDictionary Source=="/Mine;component/Themes/Palette.Blue.xaml"/>
<ResourceDictionary Source="/Mine;component/Themes/Template.xaml"/>
-->
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Run Code Online (Sandbox Code Playgroud)
注意:如果我将两个ResourceDictionaries放在Appication.Resources MergedDictionary中(注释掉theme.xaml并取消注释其他两个词典),它们都会正确加载.但是,我们的资源定义方式,这可能意味着将加载相当多的资源,而对于动态加载,我希望能够定义模板.
我一般都遇到资源字典和合并的问题,特别是涉及资源查找性能时.经过一些性能测试后,我发现ResourceDictionary.get_MergedDictionaries是具有最多命中率的调用(在ANTS探查器中检查).我们有大约300个资源字典xamls,其中很多都使用合并字典来"包含"其他样式.好吧,get_MergedDictionaries依赖于我们的应用程序的一部分,其中发生的事情并不多,大约有1000万次点击.所以我的猜测是我们正在做一些完全错误的资源字典.所以我试图重构一切,我想试图摆脱所有合并的词典.
现在来看实际问题.我试图摆脱合并的限制,但我失败了.我的理解是,当您使用StaticResource时,查找需要在当前资源之前定义资源.我做了以下简短的例子:
一个主项目和一个自定义控件库.
自定义控件库包含2个xamls.
<!-- Colors.xaml -->
<ResourceDictionary [stripped namespaces] >
<SolidColorBrush x:Key="myColor" Color="Green"/>
</ResourceDictionary>
<!-- Templates.xaml -->
<ResourceDictionary [stripped namespaces]>
<ControlTemplate x:Key="myTemplate" TargetType="Button">
<Rectangle Fill="{StaticResource myColor}"/>
</ControlTemplate>
</ResourceDictionary>
Run Code Online (Sandbox Code Playgroud)
现在在主项目中,MainWindow.xaml看起来像这样
<Window x:Class="ResourceTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/ResourceTestLib;component/Themes/Colors.xaml"/>
<ResourceDictionary Source="/ResourceTestLib;component/Themes/Template.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Button Template="{StaticResource myTemplate}"/>
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
这是理想的目标.但不幸的是,这会崩溃,因为无法找到资源"myColor".我当然知道如何修复它,在Templates.xaml中添加一个mergeddictionary并引用Colors.xaml,但我一直认为,我从未真正检查过,根据逻辑树和元素的资源查找资源.我的理解是; 按钮已创建; 尝试查找模板..发现; 尝试查找颜色,找不到自己的资源,走上去使用Windows资源.
看来我错了.所以我希望有人可以为我阐明这一点.我们大量使用WPF,尽管如此我们已经完成了很多工作,但由于一开始就有一些错误的学习行为,我们的表现非常糟糕,因为资源查找.任何帮助将不胜感激
在此先感谢最好的问候尼科
wpf performance resourcedictionary mergeddictionaries staticresource
是否可以将一个资源字典添加到另一个资源字典中?谢谢你的帮助.
我有一个WPF .net 4.5应用程序,我在合并资源字典时遇到问题.
我有与此问题和本问题完全相同的问题,但接受的解决方案对我不起作用.
我在app.xaml中声明了一个资源字典,如下所示(为简洁起见,简化):
<Application.Resources>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skin/ResourceLibrary.xaml" />
<ResourceDictionary Source="Skin/Brushes/ColorStyles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Run Code Online (Sandbox Code Playgroud)
问题: 应用程序可以在app.xaml中列出时"查看"ColorStyles dictonary,但是如果我将其移动/嵌套在ResourceLibrary.xaml中,则应用程序不会"看到"ColorStyles.xaml以及有关缺少静态资源的错误出现.
以下是我创建ResourceLibrary.xaml字典的方法(简化):
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<!-- BRUSHES AND COLORS -->
<ResourceDictionary Source="Brushes/ColorStyles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
Run Code Online (Sandbox Code Playgroud)
更改原因:我当前的资源字典组织很糟糕,我需要更改它(因为我不止一次创建对象).我希望在"Skin"文件夹中有一个资源字典,然后在子文件夹中组织剩余的样式字典,这些字典将全部合并到ResourceLibrary.xaml文件中,而后者将在app.xaml中调用.
我尝试过: 是的我尝试使用上面链接中的解决方案:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skin/ResourceLibrary.xaml"/>
</ResourceDictionary.MergedDictionaries>
<!-- Dummy Style, anything you won't use goes -->
<Style TargetType="{x:Type Rectangle}" />
</ResourceDictionary>
</Application.Resources>
Run Code Online (Sandbox Code Playgroud)
但我在虚拟样式行上得到以下错误:
错误2属性元素不能位于元素内容的中间.它们必须在内容之前或之后.
由于lisp注释,将代码更改为以下内容消除了上述错误:
<Application.Resources>
<ResourceDictionary>
<!--Global View Model Locator-->
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
<!-- Dummy Style, anything …Run Code Online (Sandbox Code Playgroud) 在我的基于桌面的WPF4应用程序中,有一个带有侧边栏菜单的大块,在每个窗口中重复,大约需要70行XAML.为了提高代码重用率,我想将XAML文件拆分为两个文件:
据我所知,有两种方法可以解决我的问题:
ResourceDictionaryUserControl/CustomControl我的问题是:
ResourceDictionary和之间有什么区别UserControl?你能给我的例子,我必须用UserControl在哪里ResourceDictionary?
你能给出一个完整的代码示例,如何将一个XAML文件的内容包含/导入到其他文件中?
PS以下是我要导出到单独的XAML文件的代码示例:
<Border Style="{StaticResource Body_SideBarMenu_Border_Settings}">
<StackPanel Style="{StaticResource Body_SideBarMenu}">
<TextBlock Style="{StaticResource Body_SideBarMenu_Title}"
Text="{x:Static res:Resources.WinApp_SideBarMenu_Title}" />
<TextBlock x:Name="SideBar_WinReports"
Style="{StaticResource Body_SideBarMenu_Item}"
Text="{x:Static res:Resources.DashListMarker}">
<Hyperlink KeyboardNavigation.TabIndex="12"
Style="{StaticResource Body_SideBarMenu_Item_Hyperlink}"
Click="Call_WinReports_Click">
<TextBlock Text="{x:Static res:Resources.WinApp_ModuleName_Reports}" />
</Hyperlink>
</TextBlock>
</StackPanel>
</Border>
Run Code Online (Sandbox Code Playgroud) 如何在WPF XAML资源字典中使用制表符和回车符?
这对我不起作用:
<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"
>
<system:String x:Key="test_Key">Tab doesnt work\tTest\rTest</system:String>
</ResourceDictionary>
Run Code Online (Sandbox Code Playgroud)
当我通过FindResource("test_key")检索它时,tab和回车字符都被删除.
我遇到过一种情况,即直接在XAML中指定浮点值并将其用作我的几个UI部件的资源非常有用.在搜索之后,我发现了大量有关如何在XAML中包含正确的程序集(mscorlib)的信息,因此您可以做到这一点.
不幸的是,我在一个实例中遇到异常,我尝试这样做.以下是重新创建情况的以下XAML:
<Window x:Class="davidtestapp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:core="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<core:Double x:Key="MyDouble">120</core:Double>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{StaticResource MyDouble}" />
<ColumnDefinition Width="40" />
<ColumnDefinition Width="40" />
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="0" Fill="Red" />
<Rectangle Grid.Column="1" Fill="Green" />
<Rectangle Grid.Column="2" Fill="Blue" />
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
当我尝试编译并运行它时,我得到一个XamlParseException,它向我说"'120'不是属性'Width'的有效值".
但是"Width"属性是双重的,为什么我不能使用定义的StaticResource来设置它?有谁知道如何做到这一点?
是否可以直接引用资源字典中另一个Brush的Brush值,而不使用Color定义(或者确切地说,将一个画笔资源复制到另一个画笔中)?
例如,我有一个Brush定义:
<SolidColorBrush x:Key="PanelBackgroundBrush" Color="White"/>
Run Code Online (Sandbox Code Playgroud)
我还有一些其他的画笔,我想和"PanelBackgroundBrush"完全相同,就像这样:
<SolidColorBrush x:Key="FolderColor" [BrushToCopy]="{StaticResource PanelBackgroundBrush}"/>
Run Code Online (Sandbox Code Playgroud)
因此"PanelBackgroundBrush"和"FolderColor"都使用白色.
我知道这可以通过使用常见的颜色定义以某种方式实现.
wpf ×10
xaml ×6
.net ×2
c# ×2
styles ×2
brush ×1
code-reuse ×1
mscorlib ×1
performance ×1
resources ×1
silverlight ×1