我想在将属性赋值给属性之前使用a Converter
来更改a的值StaticResource
.有没有办法模拟一个Binding
只会设置StaticResource
转换后的值?
有点像{Binding Value={StaticResource myStatic}, Converter={StaticResource myConverter}}
?
我一般都遇到资源字典和合并的问题,特别是涉及资源查找性能时.经过一些性能测试后,我发现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
我遇到过一种情况,即直接在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来设置它?有谁知道如何做到这一点?
我试图在一个xaml文件中创建一个新资源,并在另一个xaml文件中引用它.即我定义
<Window.Resources>
<ImageBrush x:Key="TileBrush" TileMode="Tile" ViewportUnits="Absolute" Viewport="0 0 32 32" ImageSource="MyImageButton.png" Opacity="0.3">
</ImageBrush>
</Window.Resources>
Run Code Online (Sandbox Code Playgroud)
并尝试在另一个xaml文件中使用它
<Grid>
<Button Background="{StaticResource TileBrush}" Margin="5" Padding="5" FontWeight="Bold" FontSize="14">
A Tiled Button
</Button>
</Grid>
Run Code Online (Sandbox Code Playgroud)
但是我收到错误"找不到StaticResource引用'TileBrush'." 我可以从同一个xaml文件引用该资源,但不知道如何从另一个文件中执行此操作.
我的App.xaml
文件中有几个样式:
<SolidColorBrush x:Key="styleBlue" Color="#FF4B77BE"/>
<SolidColorBrush x:Key="styleRed" Color="#FFF64747"/>
<SolidColorBrush x:Key="styleOrange" Color="#FFF89406"/>
<SolidColorBrush x:Key="styleGreen" Color="#FF1BBC9B"/>
<SolidColorBrush x:Key="styleYellow" Color="#FFF9BF3B"/>
<Style x:Key="stackpanelBackground" TargetType="StackPanel">
<Setter Property="Background" Value="{StaticResource styleBlue}"/>
</Style>
Run Code Online (Sandbox Code Playgroud)
我想改变BackgroundProperty
我的代码mainpage.xaml.cs
.
我试过用这个:
Style style = Application.Current.Resources["stackpanelBackground"] as Style;
style.Setters.SetValue(StackPanel.BackgroundProperty, "{StaticResource styleRed}");
Run Code Online (Sandbox Code Playgroud)
但我遇到了灾难性的失败异常.我认为这与此有关{StaticResource styleRed}
.有一个更好的方法吗?
我们的设计师使用Blend来设计我们的WPF应用程序.当他选择属性的本地资源时,Blend会将它们应用为{DynamicResource}
而不是a {StaticResource}
.我的猜测是Blend这样做是因为它使应用程序能够在运行时重新设置主题而无需重新启动它.
我的问题是:这个额外的查找是否有显着的性能成本?我们是否应该要求设计人员返回并手动将这些动态更改为静态?
这是一个很好的SO问题,解释了类型之间的区别:WPF中StaticResource和DynamicResource之间的区别是什么?
我有一个例外"无法找到名为'mrg'的资源.资源名称区分大小写." 当我尝试执行以下操作时:
MainWindow.xaml:
<Window.Resources>
<Thickness Left="0"
Right="1"
Bottom="2"
Top="3"
x:Key="mrg" />
</Window.Resources>
<Grid>
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:UserControl1 />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
Run Code Online (Sandbox Code Playgroud)
MainWindow.xaml.cs:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
List<string> source = new List<string>()
{
"item1",
"item2",
"item3",
"item4",
"item5",
};
DataContext = source;
}
}
Run Code Online (Sandbox Code Playgroud)
和UserControl1.xaml:
<Grid>
<TextBlock Text="{Binding}" Margin="{StaticResource mrg}" />
</Grid>
Run Code Online (Sandbox Code Playgroud)
根据msdn文章:
静态资源查找行为
查找过程检查由设置属性的元素定义的资源字典中的请求密钥.
然后,查找过程向上遍历逻辑树,到父元素及其资源字典.这一直持续到达根元素.
接下来,检查应用程序资源.应用程序资源是资源字典中由WPF应用程序的Application对象定义的资源.
因此,由于第2步,必须找到资源.但是,正如我在Locals
窗口中看到异常被捕获时那样UserControl1.Parent == null
.
我对这个问题很困惑.我可以解决它的方法是将资源放到应用程序级别.
我的问题是:为什么找不到StaticResource?
我想做这样的事情:
资源字典
<Color x:Key="clrPrimary">#5381ac</Color>
<Color x:Key="clrSecondary">#20558a</Color>
<Style TargetType="Grid" x:Key="myGrid">
<Setter Property="Background" Value="{StaticResource clrPrimary"/>
</Style>
Run Code Online (Sandbox Code Playgroud)
获得例外:
'#FF5381AC' is not a valid value for property 'Background'.
Run Code Online (Sandbox Code Playgroud)
无法将其钉牢,任何人都能指出正确的方向吗?
我想在我的窗口标题中连接我的viewmodel中的属性和来自资源文件的值.这是我没有来自资源的字符串工作:
Title="Binding Path=Description, StringFormat=Building: {0}}"
Run Code Online (Sandbox Code Playgroud)
现在我想删除"Building"字符串,并从我在其他地方使用的资源中输入一个值:
xmlns:res="clr-namespace:Project.View.Resources"
{res:Strings.TitleDescription}
Run Code Online (Sandbox Code Playgroud)
我怎样才能定义两者?我可以定义为{1}参数吗?
我有一个新手WPF问题.
想象一下,我的用户控件有一个名称空间声明,如下所示:
xmlns:system="clr-namespace:System;assembly=mscorlib"
Run Code Online (Sandbox Code Playgroud)
我有这样的用户控制资源:
<UserControl.Resources>
<system:Int32 x:Key="Today">32</system:Int32>
</UserControl.Resources>
Run Code Online (Sandbox Code Playgroud)
然后在我的用户控件的某处我有这个:
<TextBlock Text="{StaticResource Today}"/>
Run Code Online (Sandbox Code Playgroud)
这将导致错误,因为它Today
被定义为整数资源,但Text属性需要一个字符串.这个例子是人为的,但希望能说明这个问题.
问题是,如果我的资源类型与属性类型完全匹配,我有没有办法为我的资源提供转换器?类似于IValueConverter的绑定或类型转换器.
谢谢!
staticresource ×10
wpf ×10
xaml ×5
performance ×2
resources ×2
app.xaml ×1
binding ×1
c# ×1
converter ×1
converters ×1
mscorlib ×1