从另一个表单/用户控件调用方法在父表单上工作时没有发生任何事情

Calling mehtod from another form / user control nothing is happening while on parent form its working

我有一个加载不同用户控件的父窗体,但是当我尝试从用户控制器上的按钮访问父窗体上的方法时,该按钮不起作用,但如果从自己的父窗体访问相同的方法一切都很好,我排除了其余代码,这里的代码不起作用

父表上的方法:

using IT_HUB_MANAGEMENT_SOLUTION.SERVICES;

namespace IT_HUB_MANAGEMENT_SOLUTION.APP_FORMS
{
    public partial class FIRST_RUN_FRM : Form
    {
        public FIRST_RUN_FRM()
        {
            InitializeComponent();
        }

 public void NEXT_STEP_CMD()
        {
            MAIN_PANEL.Controls.Clear();
            FIRST_RUN_OBJECTS.CRYSTAL_REPORTS_CONTROL cRYSTAL_REPORTS_CONTROL = new();
            cRYSTAL_REPORTS_CONTROL.Dock = DockStyle.Fill;
            MAIN_PANEL.Controls.Add(cRYSTAL_REPORTS_CONTROL);
        }
}

这是用户控件的代码:

public partial class DOTNET_INSTALLER_CONTROL : UserControl 
    {       

        public DOTNET_INSTALLER_CONTROL()
        {
            InitializeComponent();
    }
 private void NEXT_BTN_Click(object sender, EventArgs e)
        {
            FIRST_RUN_FRM fff = new();
            fff.NEXT_STEP_CMD();
        }
}

首先,这不是 UserControl 直接调用 parent 表单方法的正常行为(至少对我而言)。通常用户控件不知道正在使用它们的 parent,对我来说,这是一个非常难闻的代码。

在您的代码中:

public partial class DOTNET_INSTALLER_CONTROL : UserControl 
{       
    public DOTNET_INSTALLER_CONTROL()
    {
        InitializeComponent();
    }
    
    private void NEXT_BTN_Click(object sender, EventArgs e)
    {
        FIRST_RUN_FRM fff = new();
        fff.NEXT_STEP_CMD();
    }
}

您只是在创建 FIRST_RUN_FORM 的新实例(同时尝试遵循命名约定),然后调用它的函数。这不会引发编译器错误,因为它是有效的 .Net 语法。您正在创建一个新的 class 并在其中调用一个 public 函数。但是,它不会在您的初始表单上显示任何内容,因为它不是同一个实例。

有两种方法可以修复此代码,我不喜欢我将向您展示的第一种方法。

  1. 您可以将parent表单实例添加到用户控件中,并在创建新的UC实例时将其传递。像这样:

     public partial class DOTNET_INSTALLER_CONTROL : UserControl 
     {
         private FIRST_RUN_FRM _parent = null;
    
         public DOTNET_INSTALLER_CONTROL(FIRST_RUN_FRM parent)
         {
             InitializeComponent();
             _parent = parent;
         }
    
         private void NEXT_BTN_Click(object sender, EventArgs e)
         {
             if (_parent == null) 
             {
                 return;
             }
    
             _parent.NEXT_STEP_CMD(); //This might throw an error not related to this question
         }
     }
    

虽然我不推荐这个。

我想要的是使用事件,这样你就不需要 UserControl 知道他们的 parent 是谁或者应该对 parent 做什么单击 UC 内的按钮时。

  1. 事件:

在用户控件中:

public partial class DOTNET_INSTALLER_CONTROL : UserControl 
{
    public event EventHandler NextButtonClicked;
    
    public DOTNET_INSTALLER_CONTROL(FIRST_RUN_FRM parent)
    {
        InitializeComponent();
        _parent = parent;
    }
    
    private void NEXT_BTN_Click(object sender, EventArgs e)
    {
        OnNextButtonClicked();
    }
    
    protected virtual void OnNextButtonClicked()
    {
        EventHandler handler = NextButtonClicked;
        handler?.Invoke(this, null);
    }
}

并且在 parent 表单中,您将订阅此事件并在它被触发时做出反应。