locked
Strange behavior with binding RRS feed

  • Question

  • Hi ,

    I'm facing a strange behavior with the TwoWay mode of WPF binding.

    Here are my source codes

    The XAML code

    <Window x:Class="TestComboBox.Window4"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window4" Height="300" Width="300"
        Loaded="Window_Loaded">
    
        <Grid Background="Black">
            <!-- Zone pour l'édition du symbole -->
            <ContentControl Margin="20">
                <ContentControl.Content>
                    <StackPanel>
                        <Slider Margin="10" Grid.Row="3" Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Stretch" Minimum="0" Maximum="100"
                            Value="{Binding Path=Code, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"></Slider>
                        <TextBox Grid.Row="3" Grid.Column="3" Width="50" Height="20" 
                            Text="{Binding Path=Code, Mode=TwoWay}">
                        </TextBox>
                        <Button Click="Button_Click">Click moi</Button>
                    </StackPanel>
                </ContentControl.Content>
            </ContentControl>
        </Grid>
    </Window>


    --------------------
    The C# Code behind of the Window

         private void Window_Loaded(object sender, RoutedEventArgs e)
            {        
                _employee = new Employee("Riana", "Rambo", 25);
                this.DataContext = _employee;
            }

    ----------------------

    The code of the business object Employee

    public class Employee 
        {
            private string _name;
            private string _firstName;
            private int _code;
    
            public string Name 
            {
                get { return _name; }
                set { _name = value; }
            }
    
            public string FirstName
            {
                get { return _firstName; }
                set { 
                    _firstName = value;
                    //NotifyPropertyChanged("FirstName");
                }
            }
    
            public int Code
            {
                get { return _code; }
                set { _code = value; }
            }
    
            public Employee(string name, string firstName, int code)
            {
                _name = name;
                _firstName = firstName;
                _code = code;
            }
    }


    -----------------------

    As you can see, my Employee class doesn't contain any dependency property nor implements INotifyPropertyChanged.
    However, every time I modify the value of one of my controls (the Slider or the TextBox), it seems that my two way binding works as expected. In other words, every time I modfy the Slider's value, it updates not only the Employee object but also the Textbox value ... The same behavior is noticed when I modify the Textbox value.

    I don't understand how my TwoWay binding can work as I thought, Two way binding works only between two dependency properties or with an object that implements INotifyPropertyChanged.

    Can someone explain me that strange behavior ?

    Thanks A lot !
    Tuesday, June 23, 2009 9:50 PM

Answers

  • Hi,

    I'd expect that the two bound properties of the different controls talk to each other since they are bound to the same property. In order to try that, you could create two properties in your Employee class that bind to the same backing field, but have different names.
    Wednesday, June 24, 2009 9:15 AM
  • Hi,

     

    -->I don't understand how my Employee object (when modified by my slider) can update my TextBox ...

     

    When you set the two way binding in XAML like you did, WPF will do the property change notification for you automatically and implicitly. We need to make the data object implemented the INotifyPropertyChanged interface or wrap the property as dependency property when we modify the data in code.

    For instance, you  change the Code value in the code behind like this:

      private void OnChangeData(object sender, RoutedEventArgs e)

            {

                (this.DataContext as Employee).Code = 100;

            }

     

    In this case, you need to implement INotifyPropertyChanged interface or wrap your property as dependency property, otherwise, the UI elements will get property notification automatically.

     

    Thanks


    Jim Zhou -MSFT
    Tuesday, June 30, 2009 8:34 AM

All replies

  • I don't understand how my TwoWay binding can work as I thought, Two way binding works only between two dependency properties or with an object that implements INotifyPropertyChanged.

    Not true.

    No notification event is necessary if the data flow is moving from binding target to binding source because the target can write directly to the source. 

    But if you modify the binding source, the target UI elements aren't going to get updated automatically.



    Mark

    Mark Salsbery Microsoft MVP - Visual C++
    Tuesday, June 23, 2009 9:55 PM
  • By implementing INotifyPropertyChanged you push changes from the source (your Employee class) to the Target (your TextBox and Slider). The changes from target to source always are Push in TwoWay mode, that's the reason the.

    If you do not want to update the source you should consider use Mode=OneTime.
    http://weblogs.asp.net/marianor/
    Tuesday, June 23, 2009 9:57 PM
  • Hi and thanks for your responses,

    In fact it works exactlly as I want it to works but I just want to understand how and why it works.

    My two UI controls (Slider and TextBox) are both binded to my Employee object in TwoWay mode.
    When I modify the slider, it updates not only the Employee object, but also my TextBox control binded on my Employee object.
    That means that my TwoWay binding between Employee object and TextBox works, despite the fact that my Employee object is not a DependencyObject nor implements INotifyPropertyChanged. I don't understand how my Employee object (when modified by my slider) can update my TextBox ...

    Hope I was more clear ..

    Riana
    Wednesday, June 24, 2009 8:25 AM
  • Hi,

    I'd expect that the two bound properties of the different controls talk to each other since they are bound to the same property. In order to try that, you could create two properties in your Employee class that bind to the same backing field, but have different names.
    Wednesday, June 24, 2009 9:15 AM
  • Effectively, when binding the two controls with two different properties (wich updates the same private field), the two way binding is broken.
    So I suppose that, as you said, in fact the UI controls updates eachover when they are bound on the same property.

    Thanks.
    Wednesday, June 24, 2009 1:05 PM
  • Hi,

     

    -->I don't understand how my Employee object (when modified by my slider) can update my TextBox ...

     

    When you set the two way binding in XAML like you did, WPF will do the property change notification for you automatically and implicitly. We need to make the data object implemented the INotifyPropertyChanged interface or wrap the property as dependency property when we modify the data in code.

    For instance, you  change the Code value in the code behind like this:

      private void OnChangeData(object sender, RoutedEventArgs e)

            {

                (this.DataContext as Employee).Code = 100;

            }

     

    In this case, you need to implement INotifyPropertyChanged interface or wrap your property as dependency property, otherwise, the UI elements will get property notification automatically.

     

    Thanks


    Jim Zhou -MSFT
    Tuesday, June 30, 2009 8:34 AM