5

I've a TextBox in a window which I'm binding to a value with the following trivial converter:

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";
    }
}

The binding itself is manifesting like so:

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

If I remove either the converter or set the mode to TwoWay no exception is raised. Why is an exception being raised otherwise, and how can I resolve or at least work around the issue?

Edit: It seems one has to provide a data context in this scenario before binding for there to be no exception raised. Why is it so?

Kaganar
  • 6,540
  • 2
  • 26
  • 59
  • 1
    What is the exception? You give a lot of data but omit the most important. – Federico Berasategui Apr 18 '13 at 21:24
  • NullReferenceException in System.Windows.Data.BindingExpression.IsValidValueForUpdate(Object value, Type sourceType) – Kaganar Apr 18 '13 at 21:26
  • You are binding `OneWayToSource` but I don't see you supplying the source property to bind to, what are you trying to bind the `TextBox.TextProperty` to, you have to bind it to something – sa_ddam213 Apr 18 '13 at 22:37
  • The source property is specified by the string variable `nm`. The data context the text box is provided with has an `nm` property (actually, the data context provided is a `DynamicObject` with `INotifyPropertyChanged`). Note that the text box has no data context as of binding. – Kaganar Apr 19 '13 at 14:19
  • Heh.. And when I provide it a data context before binding, the exception goes away. – Kaganar Apr 19 '13 at 14:22
  • Do you mind checking this at http://stackoverflow.com/questions/5528460/editing-a-datagrid-in-wpf-causes-a-system-nullreferenceexception (looks to be similar). Second, you can try to put breakpoint in convert back method. – RockWorld Apr 19 '13 at 14:34
  • I can put a breakpoint in the convert back method, but it doesn't tell me much AFAICT? What should I be looking for? There's not a whole lot to go wrong with `return "y";` – Kaganar Apr 19 '13 at 15:16

2 Answers2

5

I believe you are getting that error because you are binding the TextBox.TextProperty to nm, but the TextBox.TextProperty is null. With a two way binding it must send the value from nm to the TextBox.TextProperty first, setting it to "x", so that its not null anymore when it tries to bind back the other way. Removing the converter probably also removes the check that discovers that the TextBox.TextProperty is null and produces the exception.

So, if you were to add the line:

oj.Fe.Text = "something";

Or possibly even:

oj.Fe.Text = string.Empty;

before

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

then you should be ok.

EDIT: Actually it wasn't a null value but a null sourceType that caused the exception.

I looked in deeper with a decompiler and it looks like the exception you get is because the sourceType is null. The "IsValidValueForUpdate" function which causes the null reference exception only runs when there is a converter, which explains why you dont get it when you remove the converter. The code was run in the process of converting back, which explains why it happens with "OneWayToSource" as the binding mode. Regardless, it may just be a minor bug in the framework, so setting the datacontext before binding to provide the sourceType seems to be a good workaround.

Ben Wilde
  • 5,552
  • 2
  • 39
  • 36
  • Gave this a shot, no luck. – Kaganar Apr 19 '13 at 14:20
  • Kaganar, I looked in deeper with a decompiler and it looks like the exception you get is because the sourceType is null. The "IsValidValueForUpdate" function which causes the null reference exception only runs when there is a converter, which explains why you dont get it when you remove the converter. The code was run in the process of converting back, which explains why it happens with "OneWayToSource" as the binding mode. Regardless, it may just be a minor bug in the framework, so setting the datacontext before binding to provide the sourceType seems to be a good workaround. – Ben Wilde Apr 19 '13 at 21:51
  • Wow, that's some great investigative work, Ben. Please edit your answer to include that info so other folks can see it more easily and I'll accept your answer. – Kaganar Apr 19 '13 at 22:39
  • Just came across this and found that the parameter targetType in your converter's ConvertBack method is null when DataContext is not set, which makes sense, so you can return `Binding.DoNothing` if targetType is null. – Roger Leblanc Mar 25 '19 at 13:08
0

Can you do this? I believe constructor of Binding accepts string path and you are passing string field. So compiler works fine but WPF engine get confused. Again, I am assuming nm is binding source property which you want to get updated from Target TextBox.

Binding bnd = new Binding("nm");

I wrote this code and it worked.

<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;
            }
        }
RockWorld
  • 1,278
  • 2
  • 11
  • 24
  • My apologies, nm is actually of type `string` representing the path to the value. In this case the path is simply the name of a property of the source object. I'll edit the question and make that more clear. – Kaganar Apr 19 '13 at 15:13
  • Oh, you're setting the data context before hand. Aye, I wasn't. That doesn't really explain why it shouldn't work, however. – Kaganar Apr 19 '13 at 22:44