【问题标题】:Updating the value of another property when a DependencyProperty changes当 DependencyProperty 更改时更新另一个属性的值
【发布时间】:2019-07-08 18:00:01
【问题描述】:

我的 UserControl 中有一个 DependencyProperty 属性更改回调。该属性按预期工作,回调按预期工作。

public double CurrentFlow
{
    get { return (double)GetValue(CurrentFlowProperty); }
    set { SetValue(CurrentFlowProperty, value); }
}
public static readonly DependencyProperty CurrentFlowProperty = DependencyProperty.Register("CurrentFlow", typeof(double), typeof(MyUserControl), new PropertyMetadata(0.0, OnCurrentFlowPropertyChanged));

private static void OnCurrentFlowPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
    Console.WriteLine("CurrentFlow changed.");
}

但是,我的 UserControl 中有一个 TextBlock,我想在其中将 CurrentFlow 显示为格式化字符串。目前,我将 TextBlock 的 Text 属性绑定到 CurrentFlow,它可以工作,但我没有得到我需要的格式。 (小数点后的数字太多。)

<TextBlock Text="{Binding Path=CurrentFlow, RelativeSource={RelativeSource AncestorType=UserControl}}" />

理想情况下,我希望有一个名为 CurrentFlowString 的属性,它从 CurrentFlow 中获取值并将其格式化为我想要的格式。例如:CurrentFlow.ToString("0.00");

使用 DependencyProperties 解决此问题的最佳方法是什么?我知道如何使用常规属性执行此操作,但我有点卡在这里。

谢谢!

【问题讨论】:

  • StringFormat={0:F2} 绑定应该可以工作。
  • StringFormat=0.00 和 StringFormat=0 工作,似乎做我想做的事。花括号是否仅对某些类型的格式是必需的?

标签: wpf properties


【解决方案1】:

如果您想获得比使用StringFormat 更大的灵活性,您还可以使用自定义转换器。例如,

public class MyConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is double d)
            return $"{d:f2}";
        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return null;
    }
}

然后将其添加到您的UserControl.Resources,并在您的Binding 中使用它:

<UserControl.Resources>
    <local:MyConverter x:Key="MyConverter" />
</UserControl.Resources>

<Grid>
    <TextBlock Text="{Binding Path=CurrentFlow, RelativeSource={RelativeSource AncestorType=UserControl}, Converter={StaticResource MyConverter}}" />
</Grid>

解决方案 2: 根据您在下面的评论,这是一个替代解决方案。首先,创建一个新的依赖属性;例如FormattedCurrentFlow:

public static readonly DependencyProperty FormattedCurrentFlowProperty = DependencyProperty.Register(
    "FormattedCurrentFlow", typeof(string), typeof(MyControl), new PropertyMetadata(default(string)));

public string FormattedCurrentFlow
{
    get { return (string)GetValue(FormattedCurrentFlowProperty); }
    set { SetValue(FormattedCurrentFlowProperty, value); }
}

由于您已经有了处理CurrentFlow 更改的方法,因此当CurrentFlow 更改时更新新的FormattedCurrentFlow

private static void OnCurrentFlowPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
    var myControl = (MyControl)source;
    myControl.FormattedCurrentFlow = $"{myControl.CurrentFlow:f2}";
}

UserControl 中的TextBox 现在可以绑定到FormattedCurrentFlow

<TextBlock Text="{Binding Path=FormattedCurrentFlow, RelativeSource={RelativeSource AncestorType=UserControl}}" />

【讨论】:

  • 谢谢!幸运的是,我不需要太复杂的东西。 StringFormat=0 可以解决问题。但是,我想我的问题更多是关于如何更新其他属性,而不仅仅是 StringFormatting。例如,假设我将属性 ControlColor 设置为特定颜色。我还有一些其他属性,我想在它们自己的值中使用该颜色。就像使用 ControlColor 作为它使用的颜色的 SolidColorBrush。如果这有意义的话。
  • @n0kx 我想我明白你的意思。我在我的答案中添加了第二个解决方案,希望能解决这个问题。
猜你喜欢
  • 2020-02-21
  • 2017-04-24
  • 1970-01-01
  • 2010-10-17
  • 1970-01-01
  • 2015-04-06
  • 2016-07-21
  • 1970-01-01
  • 2013-11-02
相关资源
最近更新 更多