简体   繁体   中英

Binding - callback is called twice

I've a simple control with dependency property like this

public class StatusProgress : Control
{
    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }
    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(StatusProgress),
        new FrameworkPropertyMetadata(null, (d, e) => (d as StatusProgress).TextUpdated(e.OldValue as string)));

    private void TextUpdated(string text)
    {
        Trace.WriteLine("test");
    }
}

then I have view model

public class ViewModelPageAnalyse : ViewModelPageBase
{

    private string _progressText;
    public string ProgressText
    {
        get { return _progressText; }
        set
        {
            _progressText = value;
            OnPropertyChanged(); // base class INotifyPropertyChanged implementation
        }
    }
}

Then there is a user control (displayed in window with ContentControl ). User control is bound to view model with data template (maybe this is important)

<DataTemplate DataType="{x:Type local:ViewModelPageAnalyse}">
    <local:UserControlAnalyse/>
</DataTemplate>

And this is the control in user control

<local:StatusProgress Text="{Binding ProgressText}"/>

Now the interesting part. When ProgressText in view model is set/changed, property changed callback is called twice. I see twice "test" in the debugger output window.

More interesting: when view is changed, for some reason callback is again called with e.NewValue = null , while there is nothing directly sets ProgressText to null .

I tried already to check if value is changed in the ProgressText setter before rising event, tried to set binding mode one-way, problem still - callback is called twice with same value, call stack looks same, but there are really a lot of calls within wpf to be really sure.

While double-shot is not a real issue, it bother me. Callback with null value is what my real problem (I think they are related). Anyone knows what is wrong?


Found a reason of the first problem: it was other control with Content . During transition it created a new Model (because Content is ViewModel ) instead of reassigning existing user control. Totally my fault. Second problem still and I found this question (with workaround which is not suiting me).

Need help with

PropertyChanged callback is called with default value when ContentControl ViewModel is changed.

Which means null for Text in my case. Anyone? I couldn't figure out why is it called. My guess it is called by DataTemplate manager, if I can say so.

try to change this line:

  public static readonly DependencyProperty TextProperty =
    DependencyProperty.Register("Text", typeof(string), typeof(StatusProgress),
    new FrameworkPropertyMetadata(null, (d, e) => (d as StatusProgress).TextUpdated(e.OldValue as string)));

with this:

    public static readonly DependencyProperty TextProperty =
    DependencyProperty.Register("Text", typeof(string), typeof(StatusProgress)
    , new PropertyMetadata(""));  

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM