XAML Binding Inside and Outside a command yields different results. What?



  • This is the basic code:

    private string _test;
    
    public TestViewModel() {
        Test = "foo";
        SelectItemCommand = new DelegateCommand( () =>
        {
            Test = "baz";
        });
    }
    public string Test { get { return _test; } set { SetProperty(ref _test, value); } }
    

    In XAML a textbox then is bound to the Test property:

    <TextBox x:Name="test" Text="{Binding Test, Mode=TwoWay}" />
    

    Now, the result is foo in the textbox, no matter how often I execute the DelegateCommand (and, yes, it gets executed). The properties get changed, private and public stuff. Technically, it also doesn't matter whether I use SetProperty or change _test directly. As long as I'm outside the Command, every kind of change gets picked up.

    I'm a bit unsure whether I stumbled over a .NET 4.6 bug or something.



  • Okay, found a workaround. It's a bit weird but, well...

    So, instead of binding e.g. a textbox directly to a property of a class like this:

    public string Baz { get { return _baz; } set { SetProperty(ref _baz, value); }
    <TextBox Text="{Binding Baz, Mode=TwoWay}" />
    

    ...I have to do this:

    public class Foo {
      private string _baz;
      public string Baz { get { return _baz; } set { SetProperty(ref _baz, value); }
    }
    
    private _foo = new Foo();
    public Foo { get { return _foo; } }
    
    <Grid DataContext="{Binding Foo}">
      <TextBox Text="{Binding Baz, Mode=TwoWay}" />
    </Grid>


  • or {Binding Foo.Baz}

    I don't know how deep the delegates go in prism's delegate command, or if they extract data from expressions first for some reason, but It looks like they're doing something that loses the context of the closure.



  • Turns out, it was once again a bug in VS or .Net.

    Because now it does work. And I didn't really change the code. :rolleyes:


Log in to reply