WPF4 / C#-System.StackOverflowException崩溃应用程序

|| 在下面,您可以看到我的.xaml.cs代码。该应用程序可以正常打开。用户可以更改4个文本框。当您在文本框中编辑默认值之一,然后单击以取消选择默认值时,应用程序崩溃,并显示System.StackOverflowException错误,并说我在get {}或Calc()函数上存在无限循环或递归,取决于要编辑的文本框。我希望应用程序每次不编辑文本框时都根据Calc()函数计算数字。我还想为文本框定义一些起始值,但是还没有弄清楚该怎么做。 有什么想法可以解决循环错误和初始值定义吗? .xaml代码中的文本框遵循以下模式:
Text=\"{Binding DistanceBox}\"
完整的后台代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;

namespace ConverterApp
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new Variables();
        }
    }

    public class Variables : INotifyPropertyChanged
    {
        // Declare the PropertyChanged event.
        public event PropertyChangedEventHandler PropertyChanged;

        private double m_distanceBox;
        public double DistanceBox
        {
            get { return m_distanceBox; }
            set
            {
                //If value hasn\'t changed, don\'t do anything
                //if (m_distanceBox == value)
                //    return;
                m_distanceBox = value;
                // modify calc to read the text values
                Calc();
                // Call NotifyPropertyChanged when the source property
                // is updated.
                //if(PropertyChanged!= null)
                    NotifyPropertyChanged(\"DistanceBox\");
            }
        }

        private double m_widthBox;
        public double WidthBox
        {
            get { return m_widthBox; }
            set
            {
                m_widthBox = value;
                // modify calc to read the text values
                Calc();
                // Call NotifyPropertyChanged when the source property
                // is updated.
                NotifyPropertyChanged(\"WidthBox\");
            } 
        }

        private double m_lengthBox;
        public double LengthBox
        {
            get { return m_lengthBox; }
            set
            {
                m_lengthBox = value;
                // modify calc to read the text values
                Calc();
                // Call NotifyPropertyChanged when the source property
                // is updated.
                NotifyPropertyChanged(\"LengthBox\");
            }
        }

        private double m_lensBox;
        public double LensNeeded
        {
            get { return m_lensBox; }
            set
            {
                m_lensBox = value;
                // modify calc to read the text values
                Calc();
                // Call NotifyPropertyChanged when the source property
                // is updated.
                NotifyPropertyChanged(\"LensNeeded\");
            }
        }

        public void Calc()
        {
            double WidthBased = 2.95 * (DistanceBox / WidthBox);
            double LengthBased = 3.98 * (DistanceBox / LengthBox);

            if (WidthBased < LengthBased)
            {
                LensNeeded = Math.Round(WidthBased,2);
            }else{
                LensNeeded = Math.Round(LengthBased,2);
            }
        }

        // NotifyPropertyChanged will raise the PropertyChanged event,
        // passing the source property that is being updated.
        public void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this,
                    new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}
    
已邀请:
        在
LensNeeded
的设置器中,您叫
Calc
,calc依次设置
LensNeeded
LensNeeded
的设置器则叫
Calc
,依此类推。这种循环性导致StackOverflow。 不要在这样的setter中计算属性,而是将各个属性设置为“ virtual”(虚拟)(即时计算值,而不是从备用字段获取值),例如
public double WidthBased
{
    get { return 2.95 * (DistanceBox / WidthBox); }
}
要更新与这些属性的绑定,可以在所有相关属性的设置器中引发属性更改的事件,这里是
DistanceBox
WidthBox
的设置器。
private double m_distanceBox;
public double DistanceBox
{
    get { return m_distanceBox; }
    set
    {
        if (m_distanceBox != value)
        {
            m_distanceBox = value;
            NotifyPropertyChanged(\"DistanceBox\");
            NotifyPropertyChanged(\"WidthBased\");
        }
    }
}
初始值可以在变量类的构造函数中设置,也可以直接在字段声明中设置,例如
private double m_distanceBox = 10;
public double DistanceBox //...
    

要回复问题请先登录注册