5

我在一个窗口中有一个 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,则不会引发异常。为什么会引发异常,我该如何解决或至少解决该问题?

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

4

2 回答 2

5

我相信您会收到该错误,因为您将 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);

那你应该没问题。

编辑:实际上它不是空值,而是导致异常的空源类型。

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

于 2013-04-19T03:42:58.380 回答
0

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

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;
            }
        }
于 2013-04-19T14:47:21.170 回答