自定义控件动态更新文本属性
Custom control dynamically update text properties
我有一个基于按钮的自定义控件,可以包含如下文本:
public class TextButtonControl : Button
{
public bool AllCaps
{
get => (bool)GetValue(AllCapsProperty);
set => SetValue(AllCapsProperty, value);
}
public static readonly DependencyProperty AllCapsProperty =
DependencyProperty.Register("AllCaps", typeof(bool), typeof(TextButtonControl), new PropertyMetadata(false));
public string Text
{
get => (string)GetValue(TextProperty);
set => SetValue(TextProperty, value);
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(TextButtonControl), new PropertyMetadata(""));
static TextButtonControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(TextButtonControl), new FrameworkPropertyMetadata(typeof(TextButtonControl)));
}
}
<ControlTemplate TargetType="{x:Type local:TextButtonControl}">
<Border Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" BorderBrush="Red" BorderThickness="2">
<TextBlock Text="{TemplateBinding Text}"
FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextAlignment="Center"/>
</Border>
</ControlTemplate>
当依赖项 属性 AllCaps
更新时,如何使我的控件的文本从大写实时更改为小写(反之亦然)?
用法示例:
<!-- inside some window or user control -->
<ToggleButton x:Name="tbCaseToggle" />
<custom:TextButtonControl Text="some text" Capitalised="{Binding ElementName=tbCaseToggle, Path=IsChecked}" />
在选中或取消选中切换按钮时更改按钮内容的大小写。
Multi-value转换器
您可以为此创建一个 multi-converter,它需要一个布尔值来指示大写和文本。
public class CapitalizationConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var capitalize = (bool)values[0];
var text = (string)values[1];
// Change the capitalization here as you need
return capitalize ? text.ToUpper() : text.ToLower();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new InvalidOperationException();
}
}
在您的控件模板可以访问的资源字典中创建一个转换器实例。
<local:CapitalizationConverter x:Key="CapitalizationConverter"/>
然后在绑定 AllCaps
和 Text
属性 的控件模板中使用 multi-binding 并使用转换器根据值将文本大写AllCaps
.
<ControlTemplate x:Key="TextButtonControlTemplate" TargetType="{x:Type local:TextButtonControl}">
<Border Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" BorderBrush="Red" BorderThickness="2">
<TextBlock FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextAlignment="Center">
<TextBlock.Text>
<MultiBinding Converter="{StaticResource CapitalizationConverter}">
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="AllCaps"/>
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Text"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</Border>
</ControlTemplate>
暴露另一个属性
另一种方法是公开一个 read-only 依赖项 属性 DisplayText
.
private static readonly DependencyPropertyKey DisplayTextPropertyKey = DependencyProperty.RegisterReadOnly(
nameof(DisplayText), typeof(string), typeof(TextButtonControl),
new FrameworkPropertyMetadata(default(string), FrameworkPropertyMetadataOptions.None));
public static readonly DependencyProperty DisplayTextProperty = DisplayTextPropertyKey.DependencyProperty;
public string DisplayText
{
get => (string)GetValue(DisplayTextProperty);
private set => SetValue(DisplayTextPropertyKey, value);
}
当 AllCaps
或 Text
属性更改时重新格式化 DisplayText
属性。这仅是 AllCaps
的示例,但它对 Text
的工作方式也相同。
public static readonly DependencyProperty AllCapsProperty = DependencyProperty.Register(
"AllCaps", typeof(bool), typeof(TextButtonControl), new PropertyMetadata(false, OnAllCapsChanged));
private static void OnAllCapsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var textButtonControl = (TextButtonControl)d;
textButtonControl.DisplayText = textButtonControl.FormatText();
}
private string FormatText()
{
return AllCaps ? Text.ToUpper() : Text.ToLower();
}
在您的控件模板中,您只需绑定到 DisplayText
。
<TextBlock Text="{Binding DisplayText, RelativeSource={RelativeSource TemplatedParent}}"
FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextAlignment="Center"/>
我有一个基于按钮的自定义控件,可以包含如下文本:
public class TextButtonControl : Button
{
public bool AllCaps
{
get => (bool)GetValue(AllCapsProperty);
set => SetValue(AllCapsProperty, value);
}
public static readonly DependencyProperty AllCapsProperty =
DependencyProperty.Register("AllCaps", typeof(bool), typeof(TextButtonControl), new PropertyMetadata(false));
public string Text
{
get => (string)GetValue(TextProperty);
set => SetValue(TextProperty, value);
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(TextButtonControl), new PropertyMetadata(""));
static TextButtonControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(TextButtonControl), new FrameworkPropertyMetadata(typeof(TextButtonControl)));
}
}
<ControlTemplate TargetType="{x:Type local:TextButtonControl}">
<Border Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" BorderBrush="Red" BorderThickness="2">
<TextBlock Text="{TemplateBinding Text}"
FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextAlignment="Center"/>
</Border>
</ControlTemplate>
当依赖项 属性 AllCaps
更新时,如何使我的控件的文本从大写实时更改为小写(反之亦然)?
用法示例:
<!-- inside some window or user control -->
<ToggleButton x:Name="tbCaseToggle" />
<custom:TextButtonControl Text="some text" Capitalised="{Binding ElementName=tbCaseToggle, Path=IsChecked}" />
在选中或取消选中切换按钮时更改按钮内容的大小写。
Multi-value转换器
您可以为此创建一个 multi-converter,它需要一个布尔值来指示大写和文本。
public class CapitalizationConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var capitalize = (bool)values[0];
var text = (string)values[1];
// Change the capitalization here as you need
return capitalize ? text.ToUpper() : text.ToLower();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new InvalidOperationException();
}
}
在您的控件模板可以访问的资源字典中创建一个转换器实例。
<local:CapitalizationConverter x:Key="CapitalizationConverter"/>
然后在绑定 AllCaps
和 Text
属性 的控件模板中使用 multi-binding 并使用转换器根据值将文本大写AllCaps
.
<ControlTemplate x:Key="TextButtonControlTemplate" TargetType="{x:Type local:TextButtonControl}">
<Border Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" BorderBrush="Red" BorderThickness="2">
<TextBlock FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextAlignment="Center">
<TextBlock.Text>
<MultiBinding Converter="{StaticResource CapitalizationConverter}">
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="AllCaps"/>
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Text"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</Border>
</ControlTemplate>
暴露另一个属性
另一种方法是公开一个 read-only 依赖项 属性 DisplayText
.
private static readonly DependencyPropertyKey DisplayTextPropertyKey = DependencyProperty.RegisterReadOnly(
nameof(DisplayText), typeof(string), typeof(TextButtonControl),
new FrameworkPropertyMetadata(default(string), FrameworkPropertyMetadataOptions.None));
public static readonly DependencyProperty DisplayTextProperty = DisplayTextPropertyKey.DependencyProperty;
public string DisplayText
{
get => (string)GetValue(DisplayTextProperty);
private set => SetValue(DisplayTextPropertyKey, value);
}
当 AllCaps
或 Text
属性更改时重新格式化 DisplayText
属性。这仅是 AllCaps
的示例,但它对 Text
的工作方式也相同。
public static readonly DependencyProperty AllCapsProperty = DependencyProperty.Register(
"AllCaps", typeof(bool), typeof(TextButtonControl), new PropertyMetadata(false, OnAllCapsChanged));
private static void OnAllCapsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var textButtonControl = (TextButtonControl)d;
textButtonControl.DisplayText = textButtonControl.FormatText();
}
private string FormatText()
{
return AllCaps ? Text.ToUpper() : Text.ToLower();
}
在您的控件模板中,您只需绑定到 DisplayText
。
<TextBlock Text="{Binding DisplayText, RelativeSource={RelativeSource TemplatedParent}}"
FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextAlignment="Center"/>