【问题标题】:WPF4/C# - System.StackOverflowException Crashing AppWPF4/C# - System.StackOverflowException 崩溃应用程序
【发布时间】:2011-06-13 01:36:41
【问题描述】:

您可以在下面看到我的 .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));
            }
        }
    }
}

【问题讨论】:

    标签: c# wpf data-binding crash stack-overflow


    【解决方案1】:

    LensNeeded 的设置器中,您调用Calc,calc 依次设置LensNeededLensNeeded 的设置器调用Calc,等等。这种循环导致 StackOverflow。

    不要像这样在 setter 中计算属性,将各自的属性设为“虚拟”(即时计算值,而不是从支持字段中获取值),例如

    public double WidthBased
    {
        get { return 2.95 * (DistanceBox / WidthBox); }
    }
    

    要更新此类属性的绑定,您可以在所有相关属性的设置器中引发属性更改事件,这里将是 DistanceBoxWidthBox 的设置器。

    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 //...
    

    【讨论】:

      猜你喜欢
      • 2013-08-18
      • 2018-09-05
      • 1970-01-01
      • 1970-01-01
      • 2012-06-04
      • 1970-01-01
      • 2017-08-02
      • 1970-01-01
      • 2016-12-12
      相关资源
      最近更新 更多