System.StackOverflowException WPF MVVM

北城余情 提交于 2021-01-28 04:09:46

问题


I am trying to create a simple digital clock in WPF using MVVM. I have a label which has a binding. The code behind is simple simple and raising a property changed event each second and I have a stackoverflow exception. Can someone please help ?

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;
    }
    private string _lblValue;
    public string LabelValue
    {
        get
        {
            UpdateLabel();
            return _lblValue;
        }
        set
        {
            _lblValue = value;
            OnPropertyChanged(LabelValue);
        }
    }

    private void UpdateLabel()
    {
        _lblValue = System.DateTime.Now.ToString();
        //System.Threading.Thread.Sleep(2000);
        OnPropertyChanged("LabelValue");
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propName)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propName));
        }
    }
}

回答1:


As har07 explained it is a infinite UI loop. Here is my fix for this issue.

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;

        Task.Run(() => UpdateLabel());
    }

    private string _lblValue;
    public string LabelValue
    {
        get
        {
            return _lblValue;
        }
        set
        {
            _lblValue = value;
            OnPropertyChanged();
        }
    }

    private void UpdateLabel()
    {
        while (true)
        {
            LabelValue = System.DateTime.Now.ToString();
            System.Threading.Thread.Sleep(1000);
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propName = null)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propName));
        }
    }
}



回答2:


This is what happens :

  1. UpdateLabel() function invoked in the getter of LabelValue
  2. UpdateLabel() call OnPropertyChanged("LabelValue");
  3. Step 2 causes UI to check for updated value of property LabelValue, in other words it causes getter of LabelValue called
  4. Back to step 1.

All of above steps repeated until stackoverflow exception thrown. Try to remove step 2 to fix the problem.




回答3:


In your case it would be better to use a timer with an interval of one second.
For Example:

using System.Timers;

public partial class MainWindow : Window, INotifyPropertyChanged
{
    private Timer _clockTimer;

    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;

       _clockTimer = new Timer(1000); // The interval is in milliseconds
       _clockTimer.Elapsed += (sender, e) =>
       {
           LabelValue = System.DateTime.Now.ToString();
       };
    }

    private string _lblValue;
    public string LabelValue
    {
        get
        {
            return _lblValue;
        }
        set
        {
            _lblValue = value;
            OnPropertyChanged("LabelValue");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propName)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propName));
        }
    }
}


If you have further question on Timers, you can look on MSDN for more information.



来源:https://stackoverflow.com/questions/22549104/system-stackoverflowexception-wpf-mvvm

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!