有没有更简单的方法来更新 WPF 中的相关属性?
Is there an easier way to update related properties in WPF?
我有一个 UserControl,它将评级显示为星数。它通过将 TextBlock 的文本 属性 绑定到常规代码隐藏 属性 来实现,后者又使用整数 DependencyProperty Value.
为了在 Value 更改时更新 TextBlock,我需要从 DependencyProperty 的 PropertyChangedCallback 手动触发 INotifyPropertyChanged.PropertyChanged 事件。
这感觉太过分了。有没有更简单的方法来完成这个?
<TextBlock Text="{Binding RatingDisplay, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Rating}}}" />
public partial class Rating : UserControl, INotifyPropertyChanged
{
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(int), typeof(Rating), new PropertyMetadata(0, (sender, e) =>
{
((Rating)sender).RaisePropertyChanged(nameof(RatingDisplay));
}));
public Rating()
{
InitializeComponent();
}
public event PropertyChangedEventHandler? PropertyChanged;
public int Value
{
get => (int)GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}
public string RatingDisplay => new string('*', Value);
protected void RaisePropertyChanged(string? propertyName = null)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
您不需要在公开依赖属性的 class 中实现 INotifyPropertyChanged。依赖属性提供自己的更改通知机制。
为了更新只读依赖项 属性,像这样的东西应该可以工作:
public partial class Rating : UserControl
{
private static readonly DependencyPropertyKey RatingDisplayPropertyKey =
DependencyProperty.RegisterReadOnly(
nameof(RatingDisplay), typeof(string), typeof(Rating), null);
public static readonly DependencyProperty RatingDisplayProperty =
RatingDisplayPropertyKey.DependencyProperty;
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register(
nameof(Value), typeof(int), typeof(Rating),
new PropertyMetadata(0, (o, e) => o.SetValue(
RatingDisplayPropertyKey, new string('*', (int)e.NewValue))));
public Rating()
{
InitializeComponent();
}
public int Value
{
get => (int)GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}
public string RatingDisplay => (string)GetValue(RatingDisplayProperty);
}
或者,将值 属性 与从评分值创建字符串的绑定转换器绑定。
或者,可能是最简单的,直接访问应该更新的 UI 元素:
<TextBlock x:Name="ratingDisplay"/>
后面有这段代码:
public partial class Rating : UserControl
{
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register(
nameof(Value), typeof(int), typeof(Rating),
new PropertyMetadata(0, (o, e) =>
((Rating)o).ratingDisplay.Text = new string('*', (int)e.NewValue)));
public Rating()
{
InitializeComponent();
}
public int Value
{
get => (int)GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}
}
我有一个 UserControl,它将评级显示为星数。它通过将 TextBlock 的文本 属性 绑定到常规代码隐藏 属性 来实现,后者又使用整数 DependencyProperty Value.
为了在 Value 更改时更新 TextBlock,我需要从 DependencyProperty 的 PropertyChangedCallback 手动触发 INotifyPropertyChanged.PropertyChanged 事件。
这感觉太过分了。有没有更简单的方法来完成这个?
<TextBlock Text="{Binding RatingDisplay, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Rating}}}" />
public partial class Rating : UserControl, INotifyPropertyChanged
{
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(int), typeof(Rating), new PropertyMetadata(0, (sender, e) =>
{
((Rating)sender).RaisePropertyChanged(nameof(RatingDisplay));
}));
public Rating()
{
InitializeComponent();
}
public event PropertyChangedEventHandler? PropertyChanged;
public int Value
{
get => (int)GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}
public string RatingDisplay => new string('*', Value);
protected void RaisePropertyChanged(string? propertyName = null)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
您不需要在公开依赖属性的 class 中实现 INotifyPropertyChanged。依赖属性提供自己的更改通知机制。
为了更新只读依赖项 属性,像这样的东西应该可以工作:
public partial class Rating : UserControl
{
private static readonly DependencyPropertyKey RatingDisplayPropertyKey =
DependencyProperty.RegisterReadOnly(
nameof(RatingDisplay), typeof(string), typeof(Rating), null);
public static readonly DependencyProperty RatingDisplayProperty =
RatingDisplayPropertyKey.DependencyProperty;
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register(
nameof(Value), typeof(int), typeof(Rating),
new PropertyMetadata(0, (o, e) => o.SetValue(
RatingDisplayPropertyKey, new string('*', (int)e.NewValue))));
public Rating()
{
InitializeComponent();
}
public int Value
{
get => (int)GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}
public string RatingDisplay => (string)GetValue(RatingDisplayProperty);
}
或者,将值 属性 与从评分值创建字符串的绑定转换器绑定。
或者,可能是最简单的,直接访问应该更新的 UI 元素:
<TextBlock x:Name="ratingDisplay"/>
后面有这段代码:
public partial class Rating : UserControl
{
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register(
nameof(Value), typeof(int), typeof(Rating),
new PropertyMetadata(0, (o, e) =>
((Rating)o).ratingDisplay.Text = new string('*', (int)e.NewValue)));
public Rating()
{
InitializeComponent();
}
public int Value
{
get => (int)GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}
}