【问题标题】:C# Method ceases to function upon adding it to this.DeactivateC# 方法在将其添加到 this.Deactivate 后停止运行
【发布时间】:2023-02-24 01:25:08
【问题描述】:

在我的应用程序中,我有两种形式:主窗口和覆盖。覆盖可以最小化(通过控制它的大小)到屏幕顶部,并且主窗口可以最小化到任务栏或系统托盘。

单击叠加层上的按钮后,它可以在最小化和非最小化之间切换。单击此按钮时,主窗口会输入 FormWindowSate.Normal。

我希望它不仅在单击控制按钮时起作用,而且在叠加层失去焦点时起作用。因此我的问题是:如果我将隐藏覆盖层的代码添加到事件处理程序中,我就可以很好地隐藏覆盖层。但是当我尝试添加将主窗口返回到其原始状态的代码时,该代码在所有地方都停止运行。 这是相关代码:

在叠加形式中:

public event System.EventHandler OnShowOverlay;
public event System.EventHandler OnHideOverlay;

private void ShowOverlay()
{
    OnShowOverlay(this, null);
    this.Focus();
    OverlayPanel.Visible = true;
    this.Height = 70;
    this.InfoPanel.Location = new Point(25, 35);
    this.OverlayShowButton.Location = new Point(0, 35);
}
private void HideOverlay()
{
    if(OnHideOverlay != null)
    {
        OnHideOverlay(this, null); //!!!
        this.Focus(); 
        this.OverlayPanel.Visible = false; //***
        this.OverlayShowButton.Location = new Point(0, 0); //***
        this.InfoPanel.Location = new Point(25, 0); //***
        this.Height = 35; //***
    }
}
private void OverlayShowButton_Click(object sender, MouseEventArgs e)
{
    OverlayPanel.Visible = !OverlayPanel.Visible;
    if (OverlayPanel.Visible)
    {
        ShowOverlay();
    }
    else
    {
        HideOverlay();
    }
}

public void OverlayNoFocus(object sender, EventArgs e)
{
    HideOverlay(); //!!!
}

在叠加设计器中:

this.Deactivate += new System.EventHandler(OverlayNoFocus);

在主要形式中:

public MainForm()
{
    //irrelevant code here.

    this.overlay.OnShowOverlay += new System.EventHandler(onOverlayShow);
    this.overlay.OnHideOverlay += new System.EventHandler(onOverlayHide);
    this.overlay.Show();

    //irrelevant code here.
}

FormWindowState saveWinState = new FormWindowState();
        
void onOverlayShow(object sender, EventArgs e)
{
    saveWinState = this.WindowState;
    this.Show();
    this.WindowState = FormWindowState.Normal;
}
void onOverlayHide(object sender, EventArgs e)
{
    this.WindowState = saveWinState;
}

//!!! When OnHideOverlay is in OverlayNoFocus, the problem occur. //*** These line function as expected so long as OnHideOverlay is not in OverlayNoFocus

谁能告诉我我在这里做错了什么?

【问题讨论】:

  • Visible 属性很棘手,它不会返回您分配给它的值。相反,它会告诉您面板是否对用户实际可见。故障模式不是很明显,但 WindowState 的使用是某种提示。如果您曾经最小化覆盖表单,则 OverlayPanel.Visible 将始终返回 false。请改用布尔值。
  • 谢谢,不过我确实是。如果您查看 HideOverlay() 和 ShowOverlay() 函数。不过,我确实根据您的建议撤销了 if 语句并删除了分配。可悲的是,它并不影响我手头的实际问题......

标签: c# .net winforms


【解决方案1】:

据我了解,应用程序的初始状态可能包含一个可见的MainForm,其中叠加按钮是:

[...] 最小化(通过控制它的大小)到屏幕顶部。


点击【Overlay】,app会进入overlay展开的状态,主窗体可能是:

[...] 最小化到任务栏或系统托盘。


我相信你的问题的意图this.Deactivated是任何失去焦点都会导致恢复到原始状态,并且在以下情况下覆盖应该最小化:

  • [叠加] 按钮被第二次单击。
  • 鼠标单击发生在叠加窗体的客户矩形之外。

我的第一个建议是通过引用主窗体实例化它来使 OverlayForm 自治。同时,我会避免在Show() 方法中使用this 指针,因为如果主窗体是覆盖窗体的Owner,那么当主窗体最小化时,它会将覆盖窗体带下来!所以要避免这种情况。

public partial class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();
        _overlayForm = new OverlayForm(this);
        _overlayForm.Show(); // Avoid setting owner with 'this'.
    }
    private readonly OverlayForm _overlayForm;
}

叠加形式

在这种方案中,消息传递得到了简化,因为OverlayForm 可以直接作用于MainForm。 Deactivate 事件所要做的就是取消选中 Overlay 按钮。

public partial class OverlayForm : Form
{
    public OverlayForm(Form mainForm)
    {
        _mainForm = mainForm;
        _saveWinState = mainForm.WindowState;

        InitializeComponent();
        FormBorderStyle= FormBorderStyle.None;
        BackColor= Color.Azure;
        ShowInTaskbar= false;
        _checkBoxShowOverlay.Appearance = Appearance.Button;

        _checkBoxShowOverlay.CheckedChanged += onCheckedChangedShowOverlay;
        Deactivate += (sender, e) => _checkBoxShowOverlay.Checked = false;

        // Init and give focus back to main form.
        _mainForm.HandleCreated += (sender, e) =>
            BeginInvoke(new Action(() => onCheckedChangedShowOverlay(_checkBoxShowOverlay, EventArgs.Empty)));
    }
    private readonly Form _mainForm;
    private void onCheckedChangedShowOverlay(object sender, EventArgs e)
    {
        if (_checkBoxShowOverlay.Checked)
        {
            Size = _mainForm.Size;
            Location = _mainForm.Location;
            _saveWinState = _mainForm.WindowState;

            BeginInvoke(new Action(() =>
            {
                _mainForm.WindowState = FormWindowState.Minimized;
            }));
        }
        else
        {
            Size = new Size(
                _checkBoxShowOverlay.Width + 10,
                _checkBoxShowOverlay.Height + 10);
            Screen screen = Screen.FromControl(this);
            Location = new Point(
                screen.Bounds.X,
                screen.Bounds.Y);

            BeginInvoke(new Action(() =>
            {
                _mainForm.WindowState = _saveWinState;
                _mainForm?.Activate();
            }));
        }
    }
    FormWindowState _saveWinState;
}

【讨论】:

    猜你喜欢
    • 2017-07-24
    • 2020-01-12
    • 1970-01-01
    • 2021-05-12
    • 2015-07-15
    • 1970-01-01
    • 2014-11-23
    • 1970-01-01
    • 2015-04-27
    相关资源
    最近更新 更多