Skip to main content
Microsoft Silverlight
Home Forums General Silverlight Getting Started Why is TextChanged event for TextBox called BEFORE the ViewModel is updated (via TwoWay binding)? Now the EventHandler concludes nothing is changed!
5 replies. Latest Post by brauliod on September 29, 2009.
(0)
marcschl...
Member
38 points
39 Posts
06-22-2009 5:07 PM |
I have a DataGrid that shows items and a details form that allows editing of individual items. (Editing in the grid itself makes accidental changes more likely.) I have a Save button that updates the data. This Save button is only enabled if the data has been changed.
I tried to accomplish this via TwoWay binding. Unfortunately the events are not handled in the order that suits my needs. Am I doing something wrong?
The core code (DataContext = ViewModel):
void PeopleGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) { Person selectedPerson = PeopleGrid.SelectedItem as Person; ViewModel.CurrentPersonIndex = PeopleGrid.SelectedIndex; ViewModel.CurrentPerson = selectedPerson.Copy(); } ...
public class Person : IComparable, INotifyPropertyChanged { private string _name; public string Name { get { return _name; } set { if (_name != value) { _name = value; if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs("Name")); } } } } ...
NameTextBox.TextChanged += new TextChangedEventHandler(NameTextBox_TextChanged);
...
void NameTextBox_TextChanged(object sender, TextChangedEventArgs e) { AdjustSaveButton(); }
private void AdjustSaveButton() { Person originalPerson = ViewModel.People[ViewModel.CurrentPersonIndex]; SaveButton.IsEnabled = (originalPerson.CompareTo(ViewModel.CurrentPerson) > 0); } Some related XAML:
<data:DataGrid x:Name="PeopleGrid" ItemsSource="{Binding People}" />
<TextBox x:Name="NameTextBox" Text="{Binding CurrentPerson.Name, Mode=TwoWay}" /> The problem I face is that AdjustSaveButton() is called BEFORE the Name setter and hence SaveButton.IsEnabled remains false upon the first change in the NameTextBox. Upon the second change the setter has been called once, and hence SaveButton.IsEnabled is set to true. That's obviously one key stroke too late ...
Thanks!
Klinger
Participant
1686 points
300 Posts
06-24-2009 6:22 PM |
I have had this issue before too. The actual binding happens only after the TextChanged event handler is executed.
What makes sense to me now that I understand it better.
You can do the following to force the binding to happen:
var tb = sender as TextBox; var be = tb.GetBindingExpression(TextBox.TextProperty); if (be != null) { be.UpdateSource(); }
AdjustSaveButton();
06-24-2009 10:18 PM |
Thanks you! Are you sure this applies to Silverlight? On the Internet I see GetBindingExpression in the context of WPF but not Silverlight.
You would do me a favor if you elaborated on why it makes sense that the binding happens only after the TextChanged event handler is executed. In my scenario that does not seem to be helpful. Or maybe I should take a different approach?
06-24-2009 11:53 PM |
Yes, it works on Silverlight.
Regarding the TextChanged event.
The way I see TextChanged event is independent of the binding itself.
TextChanged means that the control property Text has changed.
It may ot may not have a binding expression attached to it.
And, because you know that the text has been changed we can all sort of
things just before the binding is actually executed.
Maybe we are missing an event here. BindingExecuted?
This behavior does not goes well with MVVM I have to agree.
06-25-2009 10:29 AM |
Must be Silverlight 3 then. Will check solution at home tonight. Thanks!
brauliod
1307 points
502 Posts
09-29-2009 8:48 AM |
Well.. encapsulated in a user control the workaround...
{
}
be.UpdateSource();