【问题标题】:Change User Control from another User Control Winforms C# [closed]从另一个用户控件更改用户控件 Winforms C# [关闭]
【发布时间】:2017-09-01 12:06:26
【问题描述】:

我在开发 SDI Windows 窗体应用程序时遇到问题。我正在使用单个窗口和不同的用户控件,这些控件会随着用户在应用程序中的进展而被换出。

问题:我有一个名为 Login 的用户控件来处理登录过程。用户成功登录后,登录用户控件应该消失,主页用户控件应该放在前面。

Login 用户控件需要移除自身并将控制权转移给 Homepage 用户控件。

我尝试将所需的用户控件作为参数发送到 MainForm 中的方法,尽管它不会更改用户控件。

我怎样才能做到这一点?我使用的方法错了吗?

请原谅我是用户控件的初学者。

【问题讨论】:

  • 请添加一些相关代码。就像你转移控制权的代码和你正在调用的方法(以及其他任何看起来合适的东西)
  • 简单的方法是将您看到的屏幕(页面)拆分为不同的UserControls(例如UserControlLoginUserControlSettings 等),然后从单一形式的Controls 中添加/删除它们(主要形式)。另一种对初学者来说可能更容易的方法是使用headless TabControl,您只需从选项卡切换到选项卡并将所有代码以单一形式(原文如此!)。从某事开始。
  • @Sinatr 感谢您的回复。我将尝试无头 tabcontrol 方法。 winforms应用程序的框架中没有类似wpf页面的东西吗?
  • "wpf pages in a frame for winforms apps" - 页面是UserControls,frame是任何可以包含children的控件。

标签: c# winforms user-controls


【解决方案1】:

您需要从表单中删除旧控件并添加新控件。

public class MainForm: Form {
    //...
    private Control currentControl;

    public void ChangeControl(Control newControl) {
        if(newControl == null) {
            throw new ArgumentNullException("newControl");
        }
        if(currentControl != null) {
            Me.Controls.Remove(currentControl);
        }
        Me.Controls.Add(newControl);
        currentControl = newControl;
    }

    public void ShowHomePage() {
        // You could use a previously created control
        this.ChangeControl(this.homePageControl);
        // Or create a new one.
        // this.ChangeControl(new HomePageControl());
    }
    //...
}

public class LoginControl: Control {
    private void LoginButton_Click(Object sender, EventArgs e) {
        if(DoLogin(...)) {
            ((MainForm)this.Parent).ShowHomePage()
        }
        else {
            // Show some error message
        }
    }
}

我个人更喜欢只通过事件与 MainForm 通信,而不是一个控件与另一个控件:

public class MainForm: Form {
    private Control currentControl;

    public void ChangeControl(Control newControl) {
        if(newControl == null) {
            throw new ArgumentNullException("newControl");
        }
        if(currentControl != null) {
            Me.Controls.Remove(currentControl);
            // Optionally you could dispose old control
            // currentControl.Dispose();
        }         
        Me.Controls.Add(newControl);
        currentControl = newControl;
    }

    // Optional generic method
    public void ChangeControl<TControl>() where TControl: Control, new() {
        this.Changecontrol(new TControl());
    }

    private void OnLoggedIn(Object sender, LoggedInEventArgs e) {
       this.ChangeControl<HomePageControl>();
    }

    private Login_ParentChanged(Object sender, EventArgs e) {
        var control = sender as LoginControl;
        if(control != null && control.Parent == null) {
            control.LoggedIn -= OnLoggedIn;
            control.ParentChanged -= Login_ParentChanged
        }
    }

    private void LogOut_Click(Object sender, EventArgs e) {
       var control = new LoginControl();
       control.LoggedIn += OnLoggedIn;
       this.ChangeControl(control);
       control.ParentChanged += Login_ParentChanged
    }
}

public class LoginControl: Control {
    public event EventHandler<LoggedInEventArgs> LoggedIn;

    private void LoginButton_Click(Object sender, EventArgs e) {
        if(DoLogin(...)) {
            if(LoggedIn != null) {
               LoggedIn(this, new LoggedInEventArgs(...))
            }
            else {
               // Show some error message
            }
        }
    }
}

【讨论】:

  • 感谢您的快速回复!我已经尝试过你的方法,它仍然不想改变。在 Login 用户控件中,我创建了 Mainform 的新对象实例并调用传递所需用户控件的方法。
  • 您无法创建 Mainform 对象的新实例,因为您不会更改原始实例。而是在 mainform 中添加一个内部静态实例变量,以便您可以调用 Mainform.instance.ChangeControl(control)
  • 我个人更喜欢 MainForm 来处理转换,并且控件只通过事件与主窗体通信。我更新了我的答案以反映这一点。
猜你喜欢
  • 1970-01-01
  • 2023-03-13
  • 2015-10-04
  • 1970-01-01
  • 2011-03-14
  • 2015-12-31
  • 1970-01-01
  • 2011-11-11
  • 2010-09-18
相关资源
最近更新 更多