【发布时间】:2014-08-22 11:58:39
【问题描述】:
情况
我制作了一个custom control MessageBar,它的样式在资源字典中定义。这个控件有一个dependency propertyMessage,正如名字所说,它将包含一条消息。
public class MessageBar : Control
{
public static readonly DependencyProperty MessageProperty =
DependencyProperty.Register("Message", typeof(string), typeof(MessageBar),
new FrameworkPropertyMetadata(string.Empty, OnMessageChanged));
static MessageBar()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MessageBar), new FrameworkPropertyMetadata(typeof(MessageBar)));
}
public string Message
{
get { return (string)GetValue(MessageProperty); }
set { SetValue(MessageProperty, value); }
}
private static void OnMessageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
MessageBar messageBar = (MessageBar)d;
if (e.NewValue != null && !string.IsNullOrWhiteSpace(e.NewValue.ToString()))
{
messageBar.Visibility = Visibility.Visible;
if (messageBar.textBlock == null)
messageBar.textBlock = messageBar.GetChildOfType<TextBlock>();
// Lots of unnecessary code
}
}
风格
<Style TargetType="{x:Type controls:MessageBar}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type controls:MessageBar}">
<Border Background="LightYellow"
BorderBrush="Black"
BorderThickness="1,0,1,1"
CornerRadius="0,0,10,10">
<StackPanel VerticalAlignment="Center"
Orientation="Horizontal"
Margin="10,0,10,0">
<!-- Actual text -->
<TextBlock Padding="4,2,4,2"
Margin="5,0,0,0"
x:Name="tbText"
Text="{TemplateBinding Message}"
FontSize="16"
FontWeight="ExtraBold" />
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
当应用程序启动时,默认样式被加载在merged dictionaries 中。用户登录后,用户选择的样式(可以与默认样式不同)加载到merged dictionaries 中。通过清除 merged dictionaries 并将正确的 resource dictionaries 添加到 merged dictionaries 来重新加载样式。
Application.Current.Resources.MergedDictionaries.Clear();
Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary()
{
Source = ...
});
// Adding happens a few times.
新样式已正确加载,并且在 UI 中也可见。 UI 正确更改。
问题
在清除并重新添加合并字典后,我尝试在 OnMessageChanged 方法中找到类型为 TextBlock 的子级时出现问题。
messageBar.textBlock = messageBar.GetChildOfType<TextBlock>();
我 100% 确定我的 GetChildOfType<>() 方法没有问题。在其他地方使用时它可以正常工作。
当我重新添加后执行此操作时,MessageBar 没有子元素。 ChildrenCount 为 0。
当合并的字典没有被清除并重新添加时,会找到一个TextBlock 类型的子元素。这就是我想要的。
我的猜测是,在清除并重新添加后,MessageBar 没有正确引用样式。因此,没有应用模板。
我已经尝试过的
我已经尝试过覆盖MessageBar 控件的ApplyTemplate() 和OnStyleChanged() 方法。但没有任何效果。
问题
如何重新加载样式,以便我(GetChildOfType<TextBlock>() 方法)可以找到TextBlock 以在OnMessageChanged 方法中设置我的消息。
提前致谢!
你好。
【问题讨论】:
-
在调用 GetChildOfType 之前尝试 messageBar.ApplyTemplate()
-
@ethicallogics 成功了。非常感谢!可以这么简单,我什至没有考虑过......如果你在答案中写下这个,我会接受它。
-
:) 我把它写成答案。
标签: c# wpf wpf-controls custom-controls resourcedictionary