【问题标题】:Detect binding error on a custom wpf textbox检测自定义 wpf 文本框上的绑定错误
【发布时间】:2016-01-03 06:03:09
【问题描述】:

我有一个自定义文本框,它有一个名为 valueProperty 的依赖属性,类型为双空。我的问题是该属性绑定到模型上的双打可空值和无可空值,当我尝试放置空值并且绑定值不可为空时,这显然失败,显示红色矩形。我想检测绑定失败并在发生这种情况时分配一个 0。所以我的问题是:有没有办法检测绑定失败?

我知道我可以使用 2 个不同的 customTextbox 来修复它,用于 nullables 和 no nullables,以及其他方式,只是想知道是否有办法检查绑定是否成功。提前致谢。

编辑>>>>>

型号:

private double _Temperature;
public double Temperature
{
    get { return _Temperature; }
    set { SetProperty(ref this._Temperature, value); }
}

private double? _Density;
public double? Density
{
    get { return _Density; }
    set { SetProperty(ref this._Density, value); }
}

视图(简化):

<local:customTextBox Value="{Binding Temperature}"/>
<local:customTextBox Value="{Binding Density}"/>

customTextBox 依赖属性:

public static readonly DependencyProperty valueProperty =            
DependencyProperty.RegisterAttached(
        "Value",
        typeof(double?),
        typeof(customTextBox),
        new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnValuePropertyChanged)
        );

    private static void OnValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        customTextBox ctb = d as customTextBox;
        ntb.Value = (double?)e.NewValue;
        //Here I can check the binding fail.
    }

使用解决方案编辑 >>>>>

我的问题有不同的解决方案,我会列举它们:

@blindmeis 解决方案。这是最简单的一种,但效力较低:

<local:customTextBox Value="{Binding Temperature, TargeNullValue=0}"/>

@Gary H 解决方案。这是我选择的解决方案,因为它准确地回答了我的要求,并且更容易在我当前的应用程序中实现:

private static void OnValuePropertyChanged(DependencyObject d,     
DependencyPropertyChangedEventArgs e)
{
    customTextBox ctb = d as customTextBox;
    ntb.Value = (double?)e.NewValue;
    if (Validation.GetHasError(d)) 
        {
            //The binding have failed
        }
}

@tomab 解决方案。我认为使用转换器是一个很好的解决方案(也许更好),但由于其他依赖属性,我仍然需要保留 customTextBox 类,并且我需要重构这么多代码。在以后的实施中,我会牢记这种方式。

感谢大家的帮助。

【问题讨论】:

  • 您是否创建了专门用于显示double 值的自定义TextBox
  • 是的,还有其他一些实用程序,比如一些依赖属性,可以轻松进行单位转换(幅度、单位等)。
  • 您描述的场景:转换、nullables 等最好使用转换器 (IValueConverter) 处理。为他们使用 Dep Properties 是一种开销。使用转换器,您将能够处理非常简单的“可空”和其他转换问题。
  • Null 有时是一个有效值,如果不是,我就不会有可为空的双精度数。如果绑定的属性在 viewModel 上,我将如何从视图中区分何时转换和何时不转换?
  • 绑定中的 TargetNullValue=0 怎么样?

标签: c# wpf mvvm binding textbox


【解决方案1】:

这是一种使用转换器的方法,其优点是您可以根据需要的任何逻辑控制输出值(将显示)的方式。

public class DoubleConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        // if you want to handle `double` too you can uncomment following lines but this is an ugly hack
        // if (value != null && value.GetType() == typeof(double))
        // {
        //    return value;
        // }
        var nullableDouble = (double?)value;
        if (nullableDouble.HasValue)
        {
            return nullableDouble.Value;
        }
        return 0;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

xaml 可能如下所示:

<UserControl.Resources>
    <converters:DoubleConverter x:Key="DoubleConverter"/>
</UserControl.Resources>

<TextBox Text="{Binding SomeValue, Converter={StaticResource DoubleConverter}}" />

SomeValue 必须是 double? 类型。

【讨论】:

  • 正如我所说,我有双可空值和不可空双值。所以,当 someValue 是双精度类型(不可为空)并且文本值为空时,您的转换器会失败,对吧?
  • 因此必须编辑您的帖子,因为这种差异非常令人困惑。想输入一些代码:VM 中的基本属性,然后 xaml 中的 TextBox?
  • 所以您想对doubledouble? 使用相同的绑定?如果您在 VM 中知道这种差异,那么您在 View 中也知道是否需要添加转换器。
  • 我编辑了代码来处理所有 3 种情况:doubledouble? 有值和 double? 没有值。但是这个解决方案很丑陋,最好依赖于不同的绑定(例如,double? 使用转换器,double 则没有转换器)
  • 是的,你是对的。正如我在问题底部所说的,我可以制作 2 个不同的自定义文本框。谢谢你的回答,你给了我一个有趣的观点。
【解决方案2】:

是的,这是一个验证错误。 您可以查询附加属性:

var errors=Validation.GetErrors(myTextbox);

有关处理和自定义验证,请参阅: Data validation in WPF

【讨论】:

  • 我认为这就是我所要求的接近方法。我一定会将此答案标记为解决方案
猜你喜欢
  • 2018-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多