【问题标题】:(WPF) Binding OneWayToSource with a converter results in immediate exception(WPF) 将 OneWayToSource 与转换器绑定会导致立即异常
【发布时间】:2013-04-18 21:12:25
【问题描述】:

我在窗口中有一个 TextBox,我使用以下简单的转换器将其绑定到一个值:

public class TestConverter : MarkupExtension, IValueConverter {
    public override object ProvideValue(IServiceProvider serviceProvider) {
        return this;
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
        return "x";
    }

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

绑定本身如下所示:

Binding bnd = new Binding(nm); // 'nm' is a string with the binding path which is just
                               // a property name of the future source object
bnd.Converter = new TestConverter();
bnd.Mode = BindingMode.OneWayToSource;
oj.Fe.SetBinding(TextBox.TextProperty, bnd); // <--- Exception occurs here

如果我移除转换器或将模式设置为 TwoWay,则不会引发异常。为什么会引发异常,我该如何解决或至少解决该问题?

编辑: 在这种情况下,似乎必须在绑定之前提供数据上下文,以免引发异常。为什么会这样?

【问题讨论】:

  • 有什么异常?您提供了很多数据,但忽略了最重要的数据。
  • System.Windows.Data.BindingExpression.IsValidValueForUpdate 中的 NullReferenceException(对象值,类型 sourceType)
  • 你正在绑定OneWayToSource,但我没有看到你提供要绑定的源属性,你想将TextBox.TextProperty绑定到什么,你必须将它绑定到某个东西跨度>
  • 源属性由字符串变量nm指定。为文本框提供的数据上下文具有nm 属性(实际上,提供的数据上下文是DynamicObjectINotifyPropertyChanged)。请注意,文本框在绑定时没有数据上下文。
  • Heh.. 当我在绑定之前为其提供数据上下文时,异常消失了。

标签: wpf data-binding converter


【解决方案1】:

我相信您会收到该错误,因为您将 TextBox.TextProperty 绑定到 nm,但 TextBox.TextProperty 为空。使用双向绑定时,它必须首先将值从 nm 发送到 TextBox.TextProperty,将其设置为“x”,以便在尝试以另一种方式绑定时不再为空。删除转换器可能还会删除发现 TextBox.TextProperty 为 null 并产生异常的检查。

所以,如果你要添加这一行:

oj.Fe.Text = "something";

甚至可能:

oj.Fe.Text = string.Empty;

之前

oj.Fe.SetBinding(TextBox.TextProperty, bnd);

那你应该没事。

编辑: 实际上,导致异常的不是 null 值,而是 null sourceType。

我使用反编译器进行了更深入的研究,看起来您得到的异常是因为 sourceType 为空。导致空引用异常的“IsValidValueForUpdate”函数仅在有转换器时运行,这解释了为什么在删除转换器时没有得到它。该代码在转换回的过程中运行,这解释了为什么它以“OneWayToSource”作为绑定模式发生。无论如何,它可能只是框架中的一个小错误,因此在绑定之前设置 datacontext 以提供 sourceType 似乎是一个很好的解决方法。

【讨论】:

  • 试一试,没有运气。
  • Kaganar,我用反编译器进行了更深入的研究,看起来你得到的异常是因为 sourceType 为空。导致空引用异常的“IsValidValueForUpdate”函数仅在有转换器时运行,这解释了为什么在删除转换器时没有得到它。该代码在转换回的过程中运行,这解释了为什么它以“OneWayToSource”作为绑定模式发生。无论如何,这可能只是框架中的一个小错误,因此在绑定之前设置 datacontext 以提供 sourceType 似乎是一个很好的解决方法。
  • 哇,这是一项很棒的调查工作,本。请编辑您的答案以包含该信息,以便其他人可以更轻松地看到它,我会接受您的答案。
  • 刚碰到这个,发现你的convertBack方法中的参数targetType在DataContext没有设置的时候是null,这很有道理,所以如果targetType为null,你可以返回Binding.DoNothing
【解决方案2】:

你能做到吗?我相信 Binding 的构造函数接受字符串路径,并且您正在传递字符串字段。所以编译器工作正常,但 WPF 引擎会感到困惑。同样,我假设 nm 是绑定源属性,您希望从 Target TextBox 获取更新。

Binding bnd = new Binding("nm");

我写了这段代码,它成功了。

<Grid>
        <TextBox Name="fe"></TextBox>
    </Grid>
// set datacontext
Binding bnd = new Binding("nm");
bnd.Converter = new TestConverter();
bnd.Mode = BindingMode.OneWayToSource;
fe.SetBinding(TextBox.TextProperty, bnd);
fe.Text = "Hi";

        public string nm 
        { 
            get
            {
                return _nm;
            }

            set
            {
                _nm = value;
            }
        }

【讨论】:

  • 抱歉,nm 实际上是string 类型,表示值的路径。在这种情况下,路径只是源对象的属性名称。我将编辑问题并使其更清楚。
  • 哦,您是在事先设置数据上下文。是的,我不是。然而,这并不能真正解释为什么它不应该工作。
猜你喜欢
  • 1970-01-01
  • 2011-12-30
  • 2011-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-24
  • 1970-01-01
  • 2014-08-27
相关资源
最近更新 更多