【问题标题】:How do I access MainWindow XAML components in a separate class?如何在单独的类中访问 MainWindow XAML 组件?
【发布时间】:2017-01-14 01:33:31
【问题描述】:

我有一个 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();

在 Utilities.cs 文件中,我像这样引用 MainWindow 组件:

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()
        {

这是我的 Utilities.cs 文件的开始:

namespace NBFoodPantry
{
    public class Utilities
    {
        NBFoodPantry.MainWindow nbMainWindow = new MainWindow();

这是我创建的几个例程,用于引用 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 之前,代码运行良好。

【问题讨论】:

  • 循环应该相当明显。 MainWindow 创建了一个 Utilities,该 Utilities 创建了一个 MainWindow,该 MainWindow 创建了一个 Utilities.... 可能的(短期)答案是将您的 MainWindow 实例传递给 to Utilities。长期的答案是使用更好的设计,比如 MVVM 和适当的 OOP,这些错误至少不太常见。
  • #BradleyDotNET -- 你有关于“像 MVVM 这样更好的设计和适当的 OOP”的例子或解释吗?我是自学 C# 并且更愿意学习执行这些任务的正确方法。谢谢!
  • 从这里开始:msdn.microsoft.com/en-us/library/dd460654(v=vs.100).aspx (OOP) 然后转到这里 msdn.microsoft.com/en-us/library/hh848246.aspx (MVVM)。我不能强烈鼓励你也找到一个好的程序员来尝试教你一些这些,你自己很难学会。如果你不知道那里有付费(也许是免费的)指导平台。许多此类网站的聊天室也可以提供帮助。不幸的是,这两个概念对于 SO 帖子来说太大了。

标签: c# wpf xaml exception-handling


【解决方案1】:

您可以在 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);
    }
}

Utilities.cs:

public class Utilities
{
    NBFoodPantry.MainWindow nbMainWindow;

    public Utilities(NBFoodPantry.MainWindow mainWindow)
    {
        nbMainWindow = mainWindow;
    }
}

【讨论】:

    【解决方案2】:

    我正在采用#BradleyDotNET 的方法。我在 Utilities.cs 文件中将我的代码更改为:

    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方法来学习正确的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-27
      • 2012-04-08
      • 1970-01-01
      • 1970-01-01
      • 2019-06-09
      • 2015-08-07
      • 2014-09-19
      • 2013-04-28
      相关资源
      最近更新 更多