C# 如何在单独的类中访问MainWindow XAML组件?

C# 如何在单独的类中访问MainWindow XAML组件?,c#,wpf,xaml,exception-handling,C#,Wpf,Xaml,Exception Handling,我有一个WPF应用程序,其中有MainWindow.xalm、MainWindow.xalm.cs和一个名为Utilities.cs的类文件。在MainWindow.xaml中,我创建了一个带有带有子菜单的侧菜单的表单。我根据用户的选择启用和禁用侧菜单。我在Utilities.cs类中创建了代码,根据传递的是true还是false来启用或禁用。在MainWindow.xaml.cs中,我引用Utilities.cs类,如下所示: NBFoodPantry.Utilities nbuUtiliti

我有一个WPF应用程序,其中有MainWindow.xalm、MainWindow.xalm.cs和一个名为Utilities.cs的类文件。在MainWindow.xaml中,我创建了一个带有带有子菜单的侧菜单的表单。我根据用户的选择启用和禁用侧菜单。我在Utilities.cs类中创建了代码,根据传递的是true还是false来启用或禁用。在MainWindow.xaml.cs中,我引用Utilities.cs类,如下所示:

NBFoodPantry.Utilities nbuUtilities = new NBFoodPantry.Utilities();
NBFoodPantry.MainWindow nbMainWindow = new MainWindow();
在Utilities.cs文件中,我引用了如下主窗口组件:

NBFoodPantry.Utilities nbuUtilities = new NBFoodPantry.Utilities();
NBFoodPantry.MainWindow nbMainWindow = new MainWindow();
以下是我的MainWindow.xaml.cs文件的开头:

namespace NBFoodPantry
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    /// 
    public partial class MainWindow : Window
    {
        SqlConnection sqlConn;
        string strErrorLogPath, strErrorLogFile, strVCClientIDSelected, strFCClientIDSelected = string.empty;
        string strVCName, strFCName, strVCButtonType, strDBInstance = string.empty;
        bool blnRowSelected, blnUpdateGridLoaded;;
        bool[] blnUpdateFields = new bool[9];
        DataRowView drvRow;
        PrintDocument printDocument1 = new PrintDocument();
        PrintPreviewDialog printPreviewDialog = new PrintPreviewDialog();
        bool isWeeklyReportViewerLoaded, isPhoneReportViewerLoaded, isDependentAgeReportViewerLoaded;
       BindingSource dataBindingSource = new BindingSource();

       NBFoodPantry.Utilities nbuUtilities = new NBFoodPantry.Utilities();

       public class Client
       {
           public string Name { get; set; }

           public DataGridRow DGRow { get; set; }
       }



        #region MainWindow
        public MainWindow()
        {
下面是我创建的两个例程,用于从主窗口引用子菜单:

public void EnableAddMenu(bool blnStatus)
    {
        nbMainWindow.miAdd.IsEnabled = blnStatus;
    }


    public void EnableAddSubMenus(bool blnStatus)
    {

        nbMainWindow.smiAddCheckinDate.IsEnabled = blnStatus;
        nbMainWindow.smiAddMonthlyVisitDate.IsEnabled = blnStatus;
        nbMainWindow.smiAddCardIssueDate.IsEnabled = blnStatus;
        nbMainWindow.smiAddDependent.IsEnabled = blnStatus;
        nbMainWindow.smiAddNote.IsEnabled = blnStatus;
    }
现在,当我尝试运行该程序时,我收到以下消息:

 "An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll"
在这一行代码中:

PrintPreviewDialog printPreviewDialog = new PrintPreviewDialog();

你知道我为什么会犯这个错误吗?如何处理这些错误?在我将复制的代码移到Utilities.cs之前,代码工作得非常好。

您可以在Utilities类中插入Utilities类,并引用已初始化的MainWindow类实例,而不是在Utilities类中创建MainWindow类的新实例。您将需要对此特定实例的引用才能启用和禁用其中的任何控件。请参考以下示例代码

MainWindow.xaml.cs:

public partial class MainWindow : Window
{
    SqlConnection sqlConn;
    string strErrorLogPath, strErrorLogFile, strVCClientIDSelected, strFCClientIDSelected = string.empty;
    string strVCName, strFCName, strVCButtonType, strDBInstance = string.empty;
    bool blnRowSelected, blnUpdateGridLoaded;;
    bool[] blnUpdateFields = new bool[9];
    DataRowView drvRow;
    PrintDocument printDocument1 = new PrintDocument();
    PrintPreviewDialog printPreviewDialog = new PrintPreviewDialog();
    bool isWeeklyReportViewerLoaded, isPhoneReportViewerLoaded, isDependentAgeReportViewerLoaded;
    BindingSource dataBindingSource = new BindingSource();

    public class Client
    {
        public string Name { get; set; }

        public DataGridRow DGRow { get; set; }
    }

    NBFoodPantry.Utilities nbuUtilities;
    public MainWindow()
    {
        InitializeComponent();
        nbuUtilities = new NBFoodPantry.Utilities(this);
    }
}
public class Utilities
{
    NBFoodPantry.MainWindow nbMainWindow;

    public Utilities(NBFoodPantry.MainWindow mainWindow)
    {
        nbMainWindow = mainWindow;
    }
}
实用程序。cs:

public partial class MainWindow : Window
{
    SqlConnection sqlConn;
    string strErrorLogPath, strErrorLogFile, strVCClientIDSelected, strFCClientIDSelected = string.empty;
    string strVCName, strFCName, strVCButtonType, strDBInstance = string.empty;
    bool blnRowSelected, blnUpdateGridLoaded;;
    bool[] blnUpdateFields = new bool[9];
    DataRowView drvRow;
    PrintDocument printDocument1 = new PrintDocument();
    PrintPreviewDialog printPreviewDialog = new PrintPreviewDialog();
    bool isWeeklyReportViewerLoaded, isPhoneReportViewerLoaded, isDependentAgeReportViewerLoaded;
    BindingSource dataBindingSource = new BindingSource();

    public class Client
    {
        public string Name { get; set; }

        public DataGridRow DGRow { get; set; }
    }

    NBFoodPantry.Utilities nbuUtilities;
    public MainWindow()
    {
        InitializeComponent();
        nbuUtilities = new NBFoodPantry.Utilities(this);
    }
}
public class Utilities
{
    NBFoodPantry.MainWindow nbMainWindow;

    public Utilities(NBFoodPantry.MainWindow mainWindow)
    {
        nbMainWindow = mainWindow;
    }
}
我正在采用布拉德利·多特内的方法。我已将Utilities.cs文件中的代码更改为:

namespace NBFoodPantry
{
    public class Utilities
    {
        NBFoodPantry.MainWindow nbMainWindow = new MainWindow();
public void EnableAddMenu(bool blnStatus)
    {
        ((MainWindow)System.Windows.Application.Current.MainWindow).miAdd.IsEnabled = blnStatus;
    }


    public void EnableAddSubMenus(bool blnStatus)
    {
        ((MainWindow)System.Windows.Application.Current.MainWindow).smiAddCheckinDate.IsEnabled = blnStatus;
        ((MainWindow)System.Windows.Application.Current.MainWindow).smiAddMonthlyVisitDate.IsEnabled = blnStatus;
        ((MainWindow)System.Windows.Application.Current.MainWindow).smiAddCardIssueDate.IsEnabled = blnStatus;
        ((MainWindow)System.Windows.Application.Current.MainWindow).smiAddDependent.IsEnabled = blnStatus;
        ((MainWindow)System.Windows.Application.Current.MainWindow).smiAddNote.IsEnabled = blnStatus;
    }

就目前而言,我还在研究MVVC方法来学习正确的方法。

循环应该相当明显。MainWindow创建一个实用程序,该实用程序创建一个MainWindow,该MainWindow创建一个实用程序。。。。可能的(短期)答案是将MainWindow实例传递给实用程序。长期的答案是使用更好的设计,如MVVM和适当的OOP,而这些错误至少不太常见。#BradleyDotNET——您有关于“更好的设计,如MVVM和适当的OOP”的示例或解释吗?我自学了c#,更愿意学习执行这些任务的正确方法。非常感谢。从这里开始:(OOP)然后到这里(MVVM)。我不能强烈地鼓励你也找一个好的程序员来教你一些这方面的东西,你自己很难学会。如果你不知道,那里有付费的(也许是免费的)指导平台。这些网站中的许多聊天室也有帮助。不幸的是,这两个概念对于一篇如此重要的文章来说太大了。