

お世話になります。

マウスのEnterで表示され、Leaveで非表示になるListBoxを作ろうとしています。

背面にPanelを敷き、その上にListBoxを配置して、PanelのMouseEnterでListBoxを表示、MouseLeaveで非表示にしようとしているのですが、うまく非表示になってくれません。

ListBoxではなく、他のFlowLayoutPanelなどでは正しく動作するのですが、ListBoxの時にはうまく動きません。

かと思いきや、ListBoxのMouseLeaveの中の処理にブレイクポイントをかけると正しく処理も走るし、その後非表示になるのですが、ブレイクポイントを外して普通に動作させるとうまくいかないのです。

以下がそのコードです。(VisualStudioExpress2015)

[code]

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace A
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void listBox1_MouseLeave(object sender, EventArgs e)
            {
                this.listBox1.Visible = false;
            }
    
            private void panel1_MouseEnter(object sender, EventArgs e)
            {
                this.listBox1.Visible = true;
            }
        }
    }
    namespace A
    {
        partial class Form1
        {
            /// <summary>
            /// Required designer variable.
            /// </summary>
            private System.ComponentModel.IContainer components = null;
    
            /// <summary>
            /// Clean up any resources being used.
            /// </summary>
            /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
            protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }
    
            #region Windows Form Designer generated code
    
            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {
                this.panel1 = new System.Windows.Forms.Panel();
                this.listBox1 = new System.Windows.Forms.ListBox();
                this.panel1.SuspendLayout();
                this.SuspendLayout();
                // 
                // panel1
                // 
                this.panel1.Controls.Add(this.listBox1);
                this.panel1.Dock = System.Windows.Forms.DockStyle.Left;
                this.panel1.Location = new System.Drawing.Point(0, 0);
                this.panel1.Name = "panel1";
                this.panel1.Size = new System.Drawing.Size(100, 253);
                this.panel1.TabIndex = 0;
                this.panel1.MouseEnter += new System.EventHandler(this.panel1_MouseEnter);
                // 
                // listBox1
                // 
                this.listBox1.Dock = System.Windows.Forms.DockStyle.Fill;
                this.listBox1.FormattingEnabled = true;
                this.listBox1.ItemHeight = 15;
                this.listBox1.Location = new System.Drawing.Point(0, 0);
                this.listBox1.Name = "listBox1";
                this.listBox1.ScrollAlwaysVisible = true;
                this.listBox1.Size = new System.Drawing.Size(100, 253);
                this.listBox1.TabIndex = 0;
                this.listBox1.MouseLeave += new System.EventHandler(this.listBox1_MouseLeave);
                // 
                // Form1
                // 
                this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F);
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.ClientSize = new System.Drawing.Size(282, 253);
                this.Controls.Add(this.panel1);
                this.Name = "Form1";
                this.Text = "Form1";
                this.panel1.ResumeLayout(false);
                this.ResumeLayout(false);
            }
    
            #endregion
    
            private System.Windows.Forms.Panel panel1;
            private System.Windows.Forms.ListBox listBox1;
        }
    }
    
[/code]

尚、PanelとListBoxのMarginとPaddingはすべて0で、隙間なくぴったり配置しています。  
PanelはDock.Left、ListBoxはDock.Fillです。

原因と対策をご教授ください。

よろしくお願いいたします。


CC BY-SA 3.0
2015-11-12T00:08:59.680
18705
2020-09-26T14:06:10.553
2015-11-12T09:06:01.453
76
9374
question
c# windows
MouseLeaveでListBoxを非表示にすることができない


ご提示のソースだとlistBox1_MouseLeaveイベントの直後にpanel1_MouseEnterイベントが走ってしまい、結果的にlistBox1のVisibleは変更されないでしょう。

イベントを以下の2種類とすることで期待の結果となるのではないでしょうか。

[code]

    private void panel1_MouseEnter(object sender, EventArgs e)
    {
        this.listBox1.Visible = true;
    }
    
    private void Form1_MouseEnter(object sender, EventArgs e)
    {
        this.listBox1.Visible = false;
    }
    
[/code]


CC BY-SA 3.0
2015-11-12T04:55:17.497
18714
2015-11-12T04:55:17.497
6040
18705
answer


綺麗な書き方ではないですが希望の動作にはなるかと思います。

[code]

    public partial class Form1 : Form {
    
        public Form1() {
            InitializeComponent();
            this.listBox1.Visible = false;
        }
    
        const int INTERVAL = 100;
        int lastLeavedTickCount = 0;
    
        private void listBox1_MouseLeave(object sender, EventArgs e) {
            this.lastLeavedTickCount = System.Environment.TickCount;
            this.listBox1.Visible = false;
        }
    
        private void panel1_MouseEnter(object sender, EventArgs e) {
            if (lastLeavedTickCount + INTERVAL > System.Environment.TickCount)
                return;
            this.listBox1.Visible = true;
        }
    
    }
    
[/code]

マウスの速度によってListBoxのMouseLeave時にPanelのMouseEnterが発生したりしなかったりなので無理矢理ですね･･･。


CC BY-SA 3.0
2015-11-25T11:03:03.540
19292
2015-11-25T11:03:03.540
4850
18705
answer