Le réseau pour les développeurs > Forums - Accueil > Windows Presentation Foundation (WPF) > Why target update before source ? A strange problem when using binding.
Poser une questionPoser une question
 

TraitéeWhy target update before source ? A strange problem when using binding.

  • jeudi 5 juin 2008 12:35ClarkZeng Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     
    A data class MyTestClass has a property IsTestChecked. Have a toggle in the data template of this class and binding the IsChecked property of the toggle button to IsTestChecked.

    <ToggleButton
    ...
    IsChecked="{Binding IsTestChecked, Mode=TwoWay}"
    ...
    />

    I find a strange thing on this binding, that when i clicke at the toggle button, the IsTestChecked property of MyTestClass

    changes before the IsChecked property of ToggleButton. In my understanding, the ToggleButton.IsChecked should be changed

    firstly and then change the MyTestClass.IsTestChecked because of the binding. I am confused about this issue.

    Can anyone give me some suggestion?

    Thank you very much!

Réponses

  • vendredi 6 juin 2008 04:10Atul GuptaMVPMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     TraitéeA du code
    I just verified the behavior by writing my own dependency property as something like below

            public static readonly DependencyProperty IsButtonCheckedProperty =

                DependencyProperty.Register("IsChecked", typeof(bool), typeof(ComboTest),

                new FrameworkPropertyMetadata(false,

                    FrameworkPropertyMetadataOptions.Journal | FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,

                    new PropertyChangedCallback(OnIsCheckedChanged)));

     

            private static void OnIsCheckedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

            {

                //this is just a dummy code to see when this method is called

                string str = "hello world";

            }

     

            public bool IsButtonChecked

            {

                get { return (bool)GetValue(IsButtonCheckedProperty); }

                set { SetValue(IsButtonCheckedProperty, value); }

            }



    I put break points in both the SetValue call and also the OnIsCheckedChanged method. On execution, I found that the breakpoint on SetValue is hit first, but before it is completed, it goes to the OnIsCheckedChanged method, finishes executing it and then comes back to SetValue method.

    If we take the ToggleButton example, it also has similar behavior. Hence before the value of IsChecked DP is updated, the call to OnIsCheckedChanged causes the event to fire, and this will cause the binding to update the value. Finally after this is done, the control comes back to SetValue call and the property assignment is completed. 

    Hope this helps !  
    MVP Client App
    • Marqué comme réponseClarkZeng vendredi 6 juin 2008 09:20
    •  

Toutes les réponses

  • vendredi 6 juin 2008 01:17ClarkZeng Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     
     Can anyone give me some suggestion?


    Thanks
  • vendredi 6 juin 2008 02:10Wodahs Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     
    Why is that causing a problem?
    John Fenton
  • vendredi 6 juin 2008 03:57Atul GuptaMVPMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     
    ClarkZeng said:

     Can anyone give me some suggestion?


    Thanks



    Is there any problem due to this behavior? I guess since ToggleButton has a property change callback set for the IsCheckedProperty, it fires before the value is updated and this causes the binding to update before you can see the value of the property update itself
    MVP Client App
  • vendredi 6 juin 2008 04:10Atul GuptaMVPMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     TraitéeA du code
    I just verified the behavior by writing my own dependency property as something like below

            public static readonly DependencyProperty IsButtonCheckedProperty =

                DependencyProperty.Register("IsChecked", typeof(bool), typeof(ComboTest),

                new FrameworkPropertyMetadata(false,

                    FrameworkPropertyMetadataOptions.Journal | FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,

                    new PropertyChangedCallback(OnIsCheckedChanged)));

     

            private static void OnIsCheckedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

            {

                //this is just a dummy code to see when this method is called

                string str = "hello world";

            }

     

            public bool IsButtonChecked

            {

                get { return (bool)GetValue(IsButtonCheckedProperty); }

                set { SetValue(IsButtonCheckedProperty, value); }

            }



    I put break points in both the SetValue call and also the OnIsCheckedChanged method. On execution, I found that the breakpoint on SetValue is hit first, but before it is completed, it goes to the OnIsCheckedChanged method, finishes executing it and then comes back to SetValue method.

    If we take the ToggleButton example, it also has similar behavior. Hence before the value of IsChecked DP is updated, the call to OnIsCheckedChanged causes the event to fire, and this will cause the binding to update the value. Finally after this is done, the control comes back to SetValue call and the property assignment is completed. 

    Hope this helps !  
    MVP Client App
    • Marqué comme réponseClarkZeng vendredi 6 juin 2008 09:20
    •  
  • vendredi 6 juin 2008 04:37Wodahs Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     
    Isn't that by design.

    DependencyPropertyChangedEventArgs e
    e.NewValue <-- contains the value you should be checking.

    Still not sure why this would be a problem?


    John Fenton

    Nice demo of how it works BTW!
    • ModifiéWodahs vendredi 6 juin 2008 04:56Kudos
    •  
  • samedi 7 juin 2008 01:46ClarkZeng Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     
    Atul Gupta said:

    I just verified the behavior by writing my own dependency property as something like below

            public static readonly DependencyProperty IsButtonCheckedProperty =

                DependencyProperty.Register("IsChecked", typeof(bool), typeof(ComboTest),

                new FrameworkPropertyMetadata(false,

                    FrameworkPropertyMetadataOptions.Journal | FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,

                    new PropertyChangedCallback(OnIsCheckedChanged)));

     

            private static void OnIsCheckedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

            {

                //this is just a dummy code to see when this method is called

                string str = "hello world";

            }

     

            public bool IsButtonChecked

            {

                get { return (bool)GetValue(IsButtonCheckedProperty); }

                set { SetValue(IsButtonCheckedProperty, value); }

            }



    I put break points in both the SetValue call and also the OnIsCheckedChanged method. On execution, I found that the breakpoint on SetValue is hit first, but before it is completed, it goes to the OnIsCheckedChanged method, finishes executing it and then comes back to SetValue method.

    If we take the ToggleButton example, it also has similar behavior. Hence before the value of IsChecked DP is updated, the call to OnIsCheckedChanged causes the event to fire, and this will cause the binding to update the value. Finally after this is done, the control comes back to SetValue call and the property assignment is completed. 

    Hope this helps !  
    MVP Client App



     Thank you very much!

    Actually, i want to control my IsChecked property with a IsCheckable flag in UI (just like MenuItem), not in data class.  That is because that i don't want user can change IsChecked by Click or Enter, but developer can change it by using the property of data class.
  • samedi 7 juin 2008 03:37Wodahs Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     
    For read only on a checkbox, you just set IsEnabled="false" you probably will also want to override the template to make it display the way you want.


    John Fenton