这是场景:
1)打开Visual Studio 2008,创建新项目......
2)选择WPF Custom Control Library作为项目类型
3)打开位于Themes文件夹中的Generic.xaml资源字典
4)添加一个简单的画笔,如:
<SolidColorBrush x:Key ="BackgroundBrush"Color ="Yellow"/>
5)从中更改嵌套Borer控件的Background属性
Background ="{TemplateBinding Background}"
至
Background ="{DynamicResource BackgroundBrush}"
现在,当您在任何项目中编译和使用此控件时,背景将不会为黄色.但是,如果您将background属性更改为StaticResource
Background ="{StaticResource BackgroundBrush}"
......它会起作用.为什么是这样?为什么StaticResource工作但不是DynamicResource?
所以,例如我有一些简单模型的MVVM WPF应用程序:
public class MyObject
{
public string F1 { get; set; }
public string F2 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
和创建3行的简单视图模型:
public class MyViewModel
{
public ObservableCollection<MyObject> Objects { get; set; }
public MyViewModel()
{
Objects = new ObservableCollection<MyObject>
{
new MyObject{F1 = "V1",F2 = "B1"},
new MyObject{F1 = "V2",F2 = "B2"},
new MyObject{F1 = "V3",F2 = "V3"}
};
}
}
Run Code Online (Sandbox Code Playgroud)
在视图中我有一个DataGrid手动定义的列和我设置的每一列CellStyle.两种样式都在Window.Resources块中定义.但对于第一列,我使用StaticResource和第二列DynamicResource
查看XAML:
<Window x:Class="WpfApplication12.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" …Run Code Online (Sandbox Code Playgroud) 设想:
我想用3个标准字体大小为我的WPF应用程序:BigFontSize,NormalFontSize,和SmallFontSize。这些是双值,它们在资源字典中定义为(sys适当定义的地方):
<sys:Double x:Key="BigFontSize">18</sys:Double>
<sys:Double x:Key="NormalFontSize">14</sys:Double>
<sys:Double x:Key="SmallFontSize">12</sys:Double>
Run Code Online (Sandbox Code Playgroud)
这很好用。但是我随机选择了 14 个作为正常尺寸。我想要的是获得系统定义的字体大小NormalFontSize。(如果这样做了,我可以使用此处描述的转换器来获取BigFontSize和SmallFontSize相对于NormalFontSize)
线索:
我从文档中发现默认字体大小存储在静态属性 (double) 中SystemFonts.MessageFontSize。但是我应该怎么做才能将该值检索到资源字典中?(我知道Binding或DynamicResource不能适用。但是,嘿,这是一个静态值,所以我怎么能申请StaticResource或x:Static或什么?)
我试过了
<sys:Double x:Key="XXXFontSize">
<StaticResource ResourceKey="SystemFonts.MessageFontSize" />
</sys:Double>
Run Code Online (Sandbox Code Playgroud)
和
<sys:Double x:Key="XXXFontSize">
<x:Static ResourceKey="SystemFonts.MessageFontSize" />
</sys:Double>
Run Code Online (Sandbox Code Playgroud)
两者似乎都不起作用(如预期)。我收到一条错误消息Cannot add content to object of type 'System.Double'.
笔记:
我不想将其封装在可以从中派生出其他样式的通用样式中(使用BasedOn),因为我有多个资源字典,并且无法使用DynamicResourcewithBasedOn
也就是说,我不能使用 …
动态资源真的是动态的吗?如果我定义一个DynamicResource,我意识到创建了一个表达式(在哪里?),直到运行时才转换为资源,但是,我不会理解的是,这个动态结构一旦构建,现在是否为"静态"
例如,如果我通过动态资源创建一个上下文菜单,那么在运行时在访问时创建的菜单项是静态的,即使它们是绑定的吗?
如果是这样,我如何在XAML中创建动态上下文菜单?
我正在尝试为我的用户控件设置样式.UserControl位于项目"控件"中,主题位于项目"MainProject"中
<UserControl x:Class="Controls.OutputPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
mc:Ignorable="d"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="OutputControl">
<!-- Style="{DynamicResource UserControlStyle}"> - I cant set the style here because the Resource Dictionary hasn't been defined yet -->
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/MainProject;component/Themes/MyTheme.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<!-- Now that the Resource Dictionary has been defined I need to set the style -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="textbox"
ScrollViewer.VerticalScrollBarVisibility="Visible"
Text="{Binding ElementName=OutputControl, Path=TextProperty}"
IsReadOnly="True"
Style="{DynamicResource OutputTextBoxStyle}"/>
</Grid>
</UserControl>
Run Code Online (Sandbox Code Playgroud) 基本上,我如何在静态类中创建自己的一组颜色,或者这样我可以这样做:
什么存在:
<Setter ... Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
Run Code Online (Sandbox Code Playgroud)
我想要的:
<Setter ... Value="{DynamicResource {x:Static MyColors.Color1}}"/>
Run Code Online (Sandbox Code Playgroud) 我有以下代码:
<Color x:Key="SelectedColor">Gold</Color>
Run Code Online (Sandbox Code Playgroud)
以及包含颜色的TabItem样式
<VisualState x:Name="Selected">
<Storyboard>
<ColorAnimationUsingKeyFrames
Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)"
Storyboard.TargetName="InnerRectangle2">
<EasingColorKeyFrame KeyTime="0" Value="{DynamicResource SelectedColor}"/>
</ColorAnimationUsingKeyFrames>
Run Code Online (Sandbox Code Playgroud)
事实证明我不能使用DynamicResource一个EasingColorKeyFrame.
我能做些什么来达到我的效果?
我需要动态设置颜色,所以才换"{DynamicResource SelectedColor}"用"{StaticResource SelectedColor}"是假表.
我已经创建了一个很小的解决方案来演示这个问题 - Selected Tab应该是Gold color,但它实际上是透明的,因为我猜VSM无法解析名为" SelectedColor" 的颜色
我是否在从.net 3.5到.net 4的步骤中遗漏了一些东西,因为我看到看似错误的行为似乎与系统的目标背道而驰.
我正在尝试使用一些示例来创建一个简单的MVVM库.我正在Twitter客户端应用程序中使用它进行一些额外的学习,并且遇到了一个很大的障碍.
情景是这样的.我的根ViewModel(TwitterClientViewModel)对象被赋予一个DialogViewModel对象的实例以供显示.DialogViewModel添加到集合中,bool HasDialogs设置为true.如有必要,将为集合和标志调用PropertyChanged事件.这部分工作非常棒.
TwitterClientViewModel的视图称为TwitterClientTemplate,并使Visible成为DialogViewTemplate(DialogViewModel的视图)托管的叠加层.托管ContentControl的模板引用了带有DynamicResource扩展的DialogViewTemplate.这在设计人员和运行时都很有用.
这是事情变得奇怪的地方.DialogViewTemplate的"主体"使用绑定到DialogViewModel.Content(类型对象)的其他内容控件来托管对话框内容.希望是使用TemplateSelector(我编写了一个很好的声明式的,但已经注释用于测试目的)我可以显示文本和交互元素.例如,在验证Twitter帐户时向用户请求详细信息.在这种情况下,PIN码.
此时,我有两个嵌套的内容控件用于对话框实现.出于测试目的,DialogViewTemplate正文中的contentcontrol使用staticresource扩展来检索EnterPINDialogTemplate(EnterPINDialogViewModel的视图).EnterPINDialogTemplate和DialogViewTemplate都在同一个文件中(前者当然是先定义的)虽然最初它们是分开的.
在运行时,staticresource扩展会抛出带有消息的XamlParseException; '为'System.Windows.Markup.StaticResourceHolder'提供价值,引发了一个异常.
和内部异常消息;
'找不到名为'EnterPINDialogTemplate'的资源.资源名称区分大小写'
使用dynamicresource返回null并在contentcontrol中显示EnterPINDialogViewModel类型的全名 - 正如资源未解析时所预期的那样.在调用FrameWorkElement.FindResource()时突破我的自定义TemplateSelector会抛出类似的异常(TryFindResource返回null).
我的第一个想法是在构建datatemplate时逻辑树被拆分,我记得早期项目中该区域的问题.我尝试使用ResourceDictionary的MergeDictionaries属性使资源字典可以在DataTemplate中使用,但设计者不喜欢这一点,这里描述了错误:http: //connect.microsoft.com/VisualStudio/feedback/details/498844/WPF的设计师抛出,InvalidCastException的
抓住那个想法.我尝试在Application,Window和TwitterClientTemplate级别合并字典,但没有运气.
以下是xaml文件.
DialogTemplates.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:VM="clr-namespace:EpicTweet.ViewModel"
xmlns:ET="clr-namespace:EpicTweet"
xmlns:T="clr-namespace:EpicTweet.Tools"
xmlns:MV="clr-namespace:MVVM;assembly=MVVM"
xmlns:Loc="clr-namespace:EpicTweet.Localization"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d">
<DataTemplate DataType="VM:EnterPINDialogViewModel" x:Key="EnterPINDialogTemplate">
<Grid d:DesignWidth="453.89" d:DesignHeight="78.92" Loc:ResXManagerProperty.ResourceManager="{x:Static ET:Language.ResourceManager}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label Content="{Loc:ResxExtension ResourceName=String_PIN, FallbackValue='<PIN>'}"/>
<TextBox Grid.Column="1"/>
<TextBlock Grid.Row="1" Grid.RowSpan="2"></TextBlock>
</Grid>
</DataTemplate>
<DataTemplate x:Key="DialogViewTemplate" DataType="MV:DialogViewModel">
<Border BorderBrush="Black" BorderThickness="1">
<Grid d:DesignWidth="277.419" d:DesignHeight="74.96" Background="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" Height="Auto" Width="Auto">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/> …Run Code Online (Sandbox Code Playgroud) 我有一个WPF应用程序,我需要允许更改外观(主要是背景和前景).所以我将它们绑定到在应用程序范围内定义的动态资源App.resources.
我还决定在我的设置窗口中使用ColorPickerfrom wpftoolkit(v2.5.0)
简化的例子
App.xaml中
<Application x:Class="WpfColors.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<SolidColorBrush x:Key="BgBrush" Color="Gray"/>
</Application.Resources>
</Application>
Run Code Online (Sandbox Code Playgroud)
带有颜色选择器的MainWindow.xaml
<Window x:Class="WpfColors.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid Name="grdBrushes"
Background="{DynamicResource ResourceKey=BgBrush}"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Width="*" Header="Element" Binding="{Binding Path=Name}"/>
<DataGridTemplateColumn Width="*" Header="Color">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<xctk:ColorPicker SelectedColor="{Binding Path=BrushColor, Mode=TwoWay}"
AvailableColorsHeader="Available" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
MainWindow.cs
using System.Linq;
using System.Windows;
using System.Windows.Media;
namespace WpfColors
{
public partial class MainWindow : Window
{
public MainWindow() …Run Code Online (Sandbox Code Playgroud) 我有以下控制。我想更改某些事件触发器的背景颜色。我想clrGray在某些事件点击时将此资源设置为颜色。
我已经尝试过以下方法,但没有成功:(
XAM:
<local:RoundedFrame x:Name="MyFrame1" HeightRequest="16" IsVisible="True" BackgroundColor="{DynamicResource clrGreen}">
Run Code Online (Sandbox Code Playgroud)
CS:
//On Some event
//Not working
MyFrame1.SetDynamicResource(MyFrame1.BackgroundColor, "clrGreen");
Run Code Online (Sandbox Code Playgroud) dynamicresource ×10
wpf ×9
c# ×3
styles ×2
.net ×1
binding ×1
color-picker ×1
colors ×1
data-binding ×1
datagrid ×1
datatemplate ×1
font-size ×1
mvvm-light ×1
resources ×1
wpftoolkit ×1
xaml ×1