我们的设计师使用Blend来设计我们的WPF应用程序.当他选择属性的本地资源时,Blend会将它们应用为{DynamicResource}
而不是a {StaticResource}
.我的猜测是Blend这样做是因为它使应用程序能够在运行时重新设置主题而无需重新启动它.
我的问题是:这个额外的查找是否有显着的性能成本?我们是否应该要求设计人员返回并手动将这些动态更改为静态?
这是一个很好的SO问题,解释了类型之间的区别:WPF中StaticResource和DynamicResource之间的区别是什么?
有没有办法在使用DynamicResource
扩展时定义转换器?有些东西
<RowDefinition Height="{Binding Source={DynamicResource someHeight}, Converter={StaticResource gridLengthConverter}}" />
Run Code Online (Sandbox Code Playgroud)
不幸的是,这给了我以下的重复:
无法在"绑定"类型的"Source"属性上设置"DynamicResourceExtension".'DynamicResourceExtension'只能在DependencyObject的DependencyProperty上设置.
注意:这是对早期设计的修订,其具有不可用于样式的限制,相当于否定其有效性.但是,这个新版本现在可以使用样式,基本上可以让你在任何可以使用绑定或动态资源的地方使用它,并获得预期的结果,使它非常有用.
从技术上讲,这不是一个问题.这是一篇文章,展示了我发现轻松使用转换器DynamicResource
作为源的方式,但为了遵循s/o的最佳实践,我将其作为问题/答案对发布.所以我在下面找到了如何做到这一点的方法,看看我的答案.希望能帮助到你!
基本上,我有一个使用DynamicResources的UserControl.应用程序使用该资源编译并运行正常,但看到此警告消息有点烦人.这让我想知道我是否做得对,这只是一个误报,或者如果我做错了,碰巧碰到它工作的裂缝.
<Grid Background="{DynamicResource AppDefaultBackgroundColor}">
...
</Grid>
Run Code Online (Sandbox Code Playgroud)
所以,如果我正确使用它,我怎么能摆脱这个警告信息呢?
如果我没有适当地使用它,它应该是什么样的,所以我没有得到警告?
PS我的应用程序工作正常,但我更喜欢在编译时没有任何编译警告.
wpf xaml compiler-warnings suppress-warnings dynamicresource
我有一个带有一些图像的ResourceDictionary:
<BitmapImage UriSource="..\Images\Bright\folder-bright.png"
x:Key="FolderItemImage" />
Run Code Online (Sandbox Code Playgroud)
我创建了一个HierarchicalTemplate
for treeview项,如下所示:
<HierarchicalDataTemplate ItemsSource="{Binding VisibleChildren}"
DataType="{x:Type st:StructureTreeItem}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ImageResourceKey}" />
<Image x:Name="iIcon2" Source="{DynamicResource FolderItemImage}"/>
<Image x:Name="iIcon"
Source="{DynamicResource {Binding ImageResourceKey}}"/>
</StackPanel>
</HierarchicalDataTemplate>
Run Code Online (Sandbox Code Playgroud)
现在,当显示项目时:
FolderItemImage
整个想法是将项目图像设置为存储在资源中的图像,但不幸的是,上面介绍的技术不起作用,现在我知道,为什么:
<Image x:Name="iIcon3" Width="16" Height="16" Margin="0, 1, 3, 1" >
<Image.Source>
<DynamicResource ResourceKey="{Binding ImageResourceKey}" />
</Image.Source>
</Image>
Run Code Online (Sandbox Code Playgroud)
结果:
PresentationFramework.dll中发生未处理的"System.Windows.Markup.XamlParseException"类型异常
附加信息:无法在"DynamicResourceExtension"类型的"ResourceKey"属性上设置"绑定".'绑定'只能在DependencyObject的DependencyProperty上设置.
所以我必须重新解释一下我的问题:如何将模型中存储的某些数据(可能是?)转换为动态资源?它必须是一个动态资源,因为我确信它可能会在运行时发生变化.
是否有任何示例可以清楚地说明静态和动态资源之间的区别.我知道静态加载一次并在启动时绑定的基本区别,而动态在运行时加载,并在每次控件重新加载时重新绑定.
提前致谢
我需要在几个地方使用相同的故事板,因此我将故事板放在我的Application.Resources中.当我尝试执行故事板时,唯一的问题是我需要引用我想要动画的目标.这是我的故事板:
<System:String x:Key="target">border2</System:String>
<Storyboard x:Key="stHeight">
<DoubleAnimationUsingKeyFrames
Storyboard.TargetProperty="(FrameworkElement.Height)"
Storyboard.TargetName="{DynamicResource target}">
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="90">
<EasingDoubleKeyFrame.EasingFunction>
<CircleEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
Run Code Online (Sandbox Code Playgroud)
我为不同对象的高度设置动画的方式是通过更改动态资源目标.当故事板在当前窗口中时,我能够这样做.但现在我想将它放在应用程序资源中,我不知道如何引用目标属性.
我之前发布的解决方案效果不错但有时很难用代码创建复杂的动画.所以我解决的另一个替代解决方案是使用表达式混合创建故事板.所以我将一个随机控件拖到表达式混合中的主窗口并创建一个随机动画.让我们说动画出现为:
<Storyboard x:Key="Storyboard1">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="grid">
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="90"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" Storyboard.TargetName="grid">
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="103"/>
</DoubleAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransformOrigin)" Storyboard.TargetName="grid">
<EasingPointKeyFrame KeyTime="0:0:1" Value="0.75,0.5"/>
</PointAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="grid">
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="75"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
Run Code Online (Sandbox Code Playgroud)
然后我复制该代码并将其粘贴到我的工作窗口而不是APP.XAML中.
然后在我的代码中假设我有一个:
<Border Name="brdBorder" BorderBrush="Silver" BorderThickness="1" Margin="328,104,0,0" Background="#FFE52E2E" HorizontalAlignment="Left" Width="94" Height="100" VerticalAlignment="Top" >
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Border.RenderTransform>
</Border>
Run Code Online (Sandbox Code Playgroud)
由于某种原因,变换组必须在那里才能为对象设置动画.无论如何,让我们说我在工作窗口中有那个寄宿生,我想用我用表达式混合创建的相同动画来制作动画.我将在代码中做的是:
Storyboard sb1 = FindResource("Storyboard1") …
Run Code Online (Sandbox Code Playgroud) 我一直在尝试一天,无济于事,在主题中创建一堆画笔,然后在自定义控件中使用DynamicResource.我做的是这样的:
所以我的问题是我找不到任何方法来定义主题中的默认值,以便我可以在应用程序中以编程方式更改它们.StaticResource怎么能找到画笔和DynamicResource呢?!
我必须补充一点,我已经创建了一个静态类,将组件资源键作为属性保存在xaml中,例如{x:Static UI:ResourceScheme.ControlBackgroundKey}.我的问题似乎与此类似:ComponentResourceKey仅作为DynamicResource问题,如果我将静态属性键替换为组件资源键的XAML标记,它仍然不起作用.
有人可以帮帮我吗?:(
我想绑定到资源(DynamicResource)并访问该资源上的属性,但有没有办法做到这一点?
(我想在visual studio的xaml编辑器中可视化构造函数的默认值.当通过DataContext引用对象或通过我的Window类中添加的属性时,无法看到这些值...)
不工作xaml :( 在作曲家工作,但不在运行时...)
<Window ... >
<Window.Resources>
<local:MyClass x:Key="myResource" />
</Window.Resources>
<StackPanel>
<Button Content="{Binding Source={DynamicResource myResource} Path=Property1}" />
<Button Content="{Binding Source={DynamicResource myResource} Path=Property2}" />
</StackPanel>
</Window>
Run Code Online (Sandbox Code Playgroud)
与类(可能需要实现INotifyPropertyChanged):
public class MyClass
{
public MyClass()
{
this.Property1 = "Ok";
this.Property2 = "Cancel";
}
public string Property1 { get; set; }
public string Property2 { get; set; }
}
Run Code Online (Sandbox Code Playgroud) Visual Studio 2010 | .NET/WPF 4.0
我认为这可能是一个WPF错误,但我似乎无法找到有关它的错误报告.为了掩盖我只是遗漏一些明显的东西的可能性,我转向stackoverflow寻求答案!
考虑一下这个xaml(代码隐藏中没有任何东西):
<Window x:Class="DownExpanders.BorderTest"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="BorderTest" Height="300" Width="300">
<Window.Resources>
<Color x:Key="BackgroundColor" R="255" G="0" B="0" A="255"/>
<Color x:Key="BorderColor" R="0" G="0" B="255" A="255"/>
<SolidColorBrush x:Key="BorderColorBrush" Color="{DynamicResource BorderColor}"/>
</Window.Resources>
<Grid>
<Border BorderThickness="20">
<Border.Background>
<SolidColorBrush Color="{DynamicResource BackgroundColor}"/>
</Border.Background>
<Border.BorderBrush>
<SolidColorBrush Color="{DynamicResource BorderColor}"/>
</Border.BorderBrush>
</Border>
<Border Margin="40" BorderBrush="{DynamicResource BorderColorBrush}" BorderThickness="20"/>
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
在设计师中,它按预期呈现.外边框有一个大的蓝色边框和一个红色背景,内边框有一个大的蓝色边框.大.
当我运行代码时,外边框没有边框 - 看起来它只是没有加载.背景设置为红色正确.同时,内边框确实正确加载其蓝色边框.
如果我将所有"DynamicResource"更改为"StaticResource",它会在运行时正确呈现.这种不一致真的让我烦恼,我无法弄明白.
所以:
编辑:
看起来它是MS决定不修复(感谢一个bug 谢里登的链接):http://connect.microsoft.com/VisualStudio/feedback/details/589898/wpf-border-borderbrush-does-not-see-变化,在动态资源