-2

I have a WPF ViewModel

class MainWindowViewModel : INotifyPropertyChanged
    {
        private string _sql;

        public string Sql
        {
            get { return _sql; }
            set
            {
                if (value == _sql) return;
                OnPropertyChanged("Sql");
                _sql = value;
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
}

I also have a XAML view with a TextBox

<Window.Resources>
    <HbmSchemaExporter:MainWindowViewModel x:Key="viewModel"/>
</Window.Resources>
....

<TextBox Grid.Row="6" Grid.Column="0" Grid.ColumnSpan="2" Text="{Binding Source={StaticResource ResourceKey=viewModel}, Path=Sql,Mode=OneWay}"/>

Code behind

    private MainWindowViewModel ViewModel
    {
        get { return Resources["viewModel"] as MainWindowViewModel; }
    }

The problem is that when in the code I do viewModel.Sql = SOMETHING the text box doesn't get updated. Debugger displays the correct value in the property but the textbox remains blank.

I also tried to change the binding to TwoWay but that only allows me to overwrite the property with a value I type in the textbox, which is something I don't really want (actually I still need to make it readonly, but it's currently out of scope).

How can I update the textbox after programmatically updating the property?

The application is basically a NHibernate DDL generator I'm writing after reading this. I need to press a "Generate SQL" button and it displays the code to run onto DB.

Community
  • 1
  • 1
usr-local-ΕΨΗΕΛΩΝ
  • 26,101
  • 30
  • 154
  • 305

1 Answers1

4
public string Sql
{
    get { return _sql; }
    set
    {
        if (value == _sql) return;
        OnPropertyChanged("Sql");
        _sql = value;
    }
}

That does not make sense. At the point that any PropertyChanged event handler is called, reading Sql will still give the old value, because you haven't updated _sql yet. You need to first update the value, and only then raise the PropertyChanged event.

  • That worked! I actually copied that code fragment from an example a few months ago and I never had yet to use databinding with a programmatically-updated property. I thought what was behind OnPropertyChanged was an asynchronous mechanism (something like "after handler finished the UI thread scans for properties marked updated") – usr-local-ΕΨΗΕΛΩΝ Mar 16 '13 at 21:41
  • 1
    @djechelon It's actually possible that some controls do update in the way you describe, there is no technical reason why they cannot. But it depends on whatever event handler gets used for `PropertyChanged`. If you have no control over it, you have to assume it might read the property directly. –  Mar 16 '13 at 22:07