我创建了自定义TextBlock控件:
[ContentProperty("Text")]
[TemplatePart(Name = TextBlockName, Type = typeof(TextBlock))]
public class CustomTextBlock : Control
{
#region Constraints
private const string TextBlockName = "Container";
#endregion
#region Private Fields
private TextBlock _tbValue;
#endregion
#region TextProperty Depenancy Property
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
"Text",
typeof(string),
typeof(CustomTextBlock),
new PropertyMetadata(null, TextChangedCallback));
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
private static void TextChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
var control = (CustomTextBlock)dependencyObject;
control.UpdateText();
}
#endregion
#region TextWrapping Dependency Property
public static readonly DependencyProperty TextWrappingProperty = DependencyProperty.Register(
"TextWrapping",
typeof(TextWrapping),
typeof(CustomTextBlock), null);
public TextWrapping TextWrapping
{
get { return (TextWrapping)GetValue(TextWrappingProperty); }
set { SetValue(TextWrappingProperty, value); }
}
#endregion
public static readonly DependencyProperty TextStyleProperty =
DependencyProperty.Register("TextStyle", typeof(Style), typeof(CustomTextBlock), new PropertyMetadata(null));
public Style TextStyle
{
get { return (Style)GetValue(TextStyleProperty); }
set { SetValue(TextStyleProperty, value); }
}
#region TextAlignment Dependency Property
public static readonly DependencyProperty TextAlignmentProperty = DependencyProperty.Register(
"TextAlignment",
typeof(TextAlignment),
typeof(CustomTextBlock),
null);
public TextAlignment TextAlignment
{
get { return (TextAlignment)GetValue(TextAlignmentProperty); }
set { SetValue(TextAlignmentProperty, value); }
}
#endregion
#region Constructor
public CustomTextBlock()
{
DefaultStyleKey = typeof(CustomTextBlock);
}
#endregion
#region Methods
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
_tbValue = GetTemplateChild(TextBlockName) as TextBlock;
UpdateText();
UpdateTextStyle();
}
private void UpdateTextStyle()
{
if (_tbValue != null && TextStyle != null)
_tbValue.Style = TextStyle;
}
private void UpdateText()
{
if (this._tbValue != null)
{
this._tbValue.Inlines.Clear();
if (!String.IsNullOrEmpty(this.Text))
{
// some stuff
}
}
}
#endregion
} 模板看起来如下:
<Style TargetType="customControls:CustomTextBlock" >
<Setter Property="Foreground" Value="{StaticResource DefaultFontBrush}"/>
<Setter Property="FontSize" Value="30"/>
<Setter Property="FontFamily" Value="{StaticResource DefaultFont}"/>
<Setter Property="TextWrapping" Value="NoWrap"/>
<Setter Property="TextAlignment" Value="Left"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="customControls:CustomTextBlock">
<TextBlock Name="Container"
TextWrapping="{TemplateBinding TextWrapping}"
TextAlignment="{TemplateBinding TextAlignment}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>一切都很好,但是当我尝试使用TextStyle和其他属性时,存在一个问题。我的期望是,这个特定的属性覆盖TextStyle中的属性,但它们没有。
<control:CustomTextBlock
TextStyle="{StaticResource StyleWithYellowForeground}"
Foreground="Red"
FontSize="20"
Text="Sample text"
/>样式"StyleWithYellowForeground“有一些设置,但它的前景设置为黄色。在我的声明中,我将前台设置为红色,因为我希望覆盖这种样式的“前台”,但它不能工作(它仍然有黄色的前景)。
你知道怎么解决这个问题吗?
我的目的是实现声明样式的优先级(最重要的是优先声明其他样式):
1)控件声明中设置的内联属性2)控件声明中的TextStyle属性集3)默认控件样式设置的Defaut属性
发布于 2014-05-22 11:07:12
问题是设置TextStyle会改变TextBlock本身的样式,因此TextBlock本身的前台设置为黄色。更改整个控件的前景不影响这一点,因为它只是TextBlock的容器。控件的样式重写其容器中的值。要更改前景,需要更改实际TextBlock的前台属性。
你想达到什么目的?也许可以简化一下..。您可能可以使整个控件的前台覆盖TextBlock的前景,但这似乎不是一个好主意。
编辑
以下是解决这一问题的两种方法:
编辑2
也许您可以尝试使用默认的TextBlock (在其中所有样式和内联属性都可以工作),并使用附加/混合行为来实现您想要的?下面是关于他们的一些信息:http://www.jayway.com/2013/03/20/behaviors-in-wpf-introduction/。
https://stackoverflow.com/questions/23804854
复制相似问题