- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试创建一些 WPF 用户控件以包含在库中以与我的团队共享,但是只读属性对我的工作方式有问题。
对于这个问题,我做了一个非常简单的用户控件,它有两个 DependencyProperties。一个基于 enum
,另一个基于选定的 enum
执行操作。 enum
用于选择按钮将使用的样式。
该应用程序是一个常规的 Wpf 应用程序,带有一个 Wpf 用户控件库作为引用。我怀疑控件库可能导致了这个问题,所以我觉得它与示例相关。
Wpf 控件库1
Dictionary1.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfControlLibrary1">
<Style x:Key="SampleStyle-Font1">
<Setter Property="TextElement.FontFamily" Value="Wingdings" />
<Setter Property="TextElement.FontSize" Value="30" />
</Style>
<Style x:Key="SampleStyle-Font2">
<Setter Property="TextElement.FontFamily" Value="Elephant" />
<Setter Property="TextElement.FontSize" Value="30" />
</Style>
<Style x:Key="SampleStyle-Font3">
<Setter Property="TextElement.FontFamily" Value="Times New Roman" />
<Setter Property="TextElement.FontSize" Value="30" />
</Style>
</ResourceDictionary>
用户控件1.xaml:
<UserControl x:Class="WpfControlLibrary1.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfControlLibrary1"
mc:Ignorable="d"
d:DesignHeight="100" d:DesignWidth="200">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<UserControl.Template>
<ControlTemplate>
<Button Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:UserControl1}}, Path=Command}">
<StackPanel>
<Label Style="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:UserControl1}}, Path=ReadOnlyStyle}" Content="{Binding Path=Content, RelativeSource={x:Static RelativeSource.TemplatedParent}}"></Label>
</StackPanel>
</Button>
</ControlTemplate>
</UserControl.Template>
</UserControl>
UserControl1.xaml.cs
namespace WpfControlLibrary1 {
using System.Windows;
using System.Windows.Controls;
/// <summary>
/// Interaction logic for UserControl1.xaml
/// </summary>
public partial class UserControl1 : UserControl {
public enum StyleSelector {
Style1,
Style2,
Style3
}
public static DependencyProperty SelectedStyleProperty =
DependencyProperty.Register("SelectedStyle", typeof(StyleSelector), typeof(UserControl1), new PropertyMetadata(ReadOnlyStyle_Changed));
private static readonly DependencyPropertyKey ReadOnlyStylePropertyKey =
DependencyProperty.RegisterReadOnly("ReadOnlyStyle", typeof(Style),
typeof(UserControl1), null);
public UserControl1() {
InitializeComponent();
}
public StyleSelector SelectedStyle {
get => (StyleSelector)GetValue(SelectedStyleProperty);
set => SetValue(SelectedStyleProperty, value);
}
public Style ReadOnlyStyle => (Style)GetValue(ReadOnlyStylePropertyKey.DependencyProperty);
private static void ReadOnlyStyle_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e) {
if (!(d is UserControl1 userControl1)) {
return;
}
Style style;
switch (userControl1.SelectedStyle) {
case StyleSelector.Style1:
style = (Style)userControl1.FindResource("SampleStyle-Font1");
break;
case StyleSelector.Style2:
style = (Style)userControl1.FindResource("SampleStyle-Font2");
break;
case StyleSelector.Style3:
style = (Style)userControl1.FindResource("SampleStyle-Font3");
break;
default:
style = (Style)userControl1.FindResource("SampleStyle-Font1");
break;
}
userControl1.SetValue(ReadOnlyStylePropertyKey, style);
}
}
}
Wpf 应用程序
主窗口.xaml:
<Window x:Class="ReadOnlyDependencyPropertiesWithUserControls.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ReadOnlyDependencyPropertiesWithUserControls"
xmlns:wpfControlLibrary1="clr-namespace:WpfControlLibrary1;assembly=WpfControlLibrary1"
mc:Ignorable="d"
Title="Example" Height="200" Width="400">
<StackPanel>
<wpfControlLibrary1:UserControl1 SelectedStyle="Style1" Content="This is the first control"></wpfControlLibrary1:UserControl1>
<wpfControlLibrary1:UserControl1 SelectedStyle="Style2" Content="This is the second control"></wpfControlLibrary1:UserControl1>
<wpfControlLibrary1:UserControl1 SelectedStyle="Style3" Content="This is the third control"></wpfControlLibrary1:UserControl1>
</StackPanel>
</Window>
下面的输出显示第一个控件不显示样式
。如果我运行该应用程序,使用 Live 编辑器将其切换到 Style2,然后返回到 Style1,WingDings 字体会接管,但在重新运行时它不会。这看起来确实像是一个依赖属性问题,但据我所知我的设置是正确的,尤其是因为其他两个控件似乎可以正常工作。
最佳答案
它不起作用的原因是因为您在 SelectedStyle
属性更改处理程序中分配了 ReadOnlyStyle
属性值。由于 SelectedStyle
属于 StyleSelector
类型,它是一个 enum
,并且您没有明确为此属性分配默认值,它将具有默认值default(StyleSelector)
由框架分配,恰好是 StyleSelector.Style1
。即使您在第一个控件上将该值显式分配给此属性,该值也不会真正改变,因此不会调用处理程序,因此 ReadOnlyStyle
仍然是 null
,因此,你得到你得到的(一个具有默认样式的 Label
)。
为了解决这个问题,您应该为 ReadOnlyStyle
分配初始值。但是由于样式保存在资源字典中,您不能在构造函数中执行此操作。分配初始值的一个好点是:
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
var style = (Style)userControl1.FindResource("SampleStyle-Font1");
SetValue(ReadOnlyStylePropertyKey, style);
}
实现目标的“WPF 方式”是使用触发器。所以首先你可以从你的控件中删除不必要的代码:
public partial class UserControl1 : UserControl
{
public enum StyleSelector
{
Style1,
Style2,
Style3
}
public static DependencyProperty SelectedStyleProperty =
DependencyProperty.Register("SelectedStyle", typeof(StyleSelector), typeof(UserControl1));
public UserControl1()
{
InitializeComponent();
}
public StyleSelector SelectedStyle
{
get => (StyleSelector)GetValue(SelectedStyleProperty);
set => SetValue(SelectedStyleProperty, value);
}
}
然后修改你的模板:
<ControlTemplate>
<Button Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:UserControl1}}, Path=Command}">
<StackPanel>
<Label x:Name="PART_Label" Content="{Binding Path=Content, RelativeSource={x:Static RelativeSource.TemplatedParent}}" />
</StackPanel>
</Button>
<ControlTemplate.Triggers>
<Trigger Property="local:UserControl1.SelectedStyle" Value="Style1">
<Setter TargetName="PART_Label" Property="Style" Value="{StaticResource SampleStyle-Font1}" />
</Trigger>
<Trigger Property="local:UserControl1.SelectedStyle" Value="Style2">
<Setter TargetName="PART_Label" Property="Style" Value="{StaticResource SampleStyle-Font2}" />
</Trigger>
<Trigger Property="local:UserControl1.SelectedStyle" Value="Style3">
<Setter TargetName="PART_Label" Property="Style" Value="{StaticResource SampleStyle-Font3}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
这里有两件重要的事情:
Label
需要有 x:Name
以便在 Setter.TargetName
中引用它Trigger.Property
值需要完全限定,因为 ControlTemplate
没有设置 TargetType
。关于c# - 只读依赖属性更新但在首次使用时不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53887412/
今天有小伙伴给我留言问到,try{...}catch(){...}是什么意思?它用来干什么? 简单的说 他们是用来捕获异常的 下面我们通过一个例子来详细讲解下
我正在努力提高网站的可访问性,但我不知道如何在页脚中标记社交媒体链接列表。这些链接指向我在 facecook、twitter 等上的帐户。我不想用 role="navigation" 标记这些链接,因
说现在是 6 点,我有一个 Timer 并在 10 点安排了一个 TimerTask。之后,System DateTime 被其他服务(例如 ntp)调整为 9 点钟。我仍然希望我的 TimerTas
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我就废话不多说了,大家还是直接看代码吧~ ? 1
Maven系列1 1.什么是Maven? Maven是一个项目管理工具,它包含了一个对象模型。一组标准集合,一个依赖管理系统。和用来运行定义在生命周期阶段中插件目标和逻辑。 核心功能 Mav
我是一名优秀的程序员,十分优秀!