阻止组合框在选择项目之前折叠下拉菜单

huangapple go评论72阅读模式
英文:

Prevent dropdown of Combo Box collapse before item selected

问题

以下是您要翻译的内容:

"I want when the button in Pagination is clicked, the dropdown of the Combo Box is still opened, so I can see the result of the pagination in the items of the Combo Box and the dropdown closed when I selected item of Combo Box.

My problem is when I click the buttons in Pagination, the dropdown of the Combo Box closed, so I can't see the result of the pagination.

How to prevent dropdown of Combo Box collapse before item selected in C# Win Form?"

CtechComboBoxPagination.cs

using static DiscountCard.View.CustomControl.CtechPagination;

namespace DiscountCard.View.CustomControl
{
    public partial class CtechComboBoxPagination : ComboBox
    {
        public CtechPagination? Pagination { get; set; }

        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;  // Turn on WS_EX_COMPOSITED
                return cp;
            }
        }

        public CtechComboBoxPagination()
        {
            InitializeComponent();

            DoubleBuffered = true;
            DropDownStyle = ComboBoxStyle.DropDownList;
            DrawMode = DrawMode.OwnerDrawFixed;
            Font = new Font("Consolas", 11F, FontStyle.Regular, GraphicsUnit.Point);

            Pagination = new CtechPagination();
            Pagination.SetInitialize(Enumerable.Range(0, 100).AsQueryable(), newContent: true, PaginationPosition.LastPage);
            Pagination.FirstPaginationButton_Click += Pagination_FirstPaginationButton_Click;
            Pagination.PrevPaginationButton_Click += Pagination_PrevPaginationButton_Click;
            Pagination.NextPaginationButton_Click += Pagination_NextPaginationButton_Click;
            Pagination.LastPaginationButton_Click += Pagination_LastPaginationButton_Click;
        }

        private void Pagination_FirstPaginationButton_Click(object? sender, EventArgs e)
        {
            DroppedDown = true;
        }
        private void Pagination_PrevPaginationButton_Click(object? sender, EventArgs e)
        {
            DroppedDown = true;
        }
        private void Pagination_NextPaginationButton_Click(object? sender, EventArgs e)
        {
            DroppedDown = true;
        }
        private void Pagination_LastPaginationButton_Click(object? sender, EventArgs e)
        {
            DroppedDown = true;
        }

        protected override void OnDrawItem(DrawItemEventArgs e)
        {
            e.DrawBackground();

            if (e.Index < 0 || e.Index >= Items.Count)
            {
                return;
            }
            var item = Items[e.Index];
            String? text = item == null ? "(null)" : item.ToString();

            TextRenderer.DrawText(e.Graphics, text, e.Font, e.Bounds, e.ForeColor, TextFormatFlags.Left | TextFormatFlags.VerticalCenter);

            base.OnDrawItem(e);
        }

        protected override void OnDropDown(EventArgs e)
        {
            base.OnDropDown(e);

            if (Pagination == null)
            {
                return;
            }

            // for test
            if (Pagination.CurrentPage != null)
            {
                Items.Clear();
                for (int i = Pagination.CurrentPage.MinIndex; i <= Pagination.CurrentPage.MaxIndex; i++)
                {
                    Items.Add(i);
                }
            }

            Pagination.Margin = new Padding(0);
            Pagination.MinimumSize = new Size(this.Width, 30);

            ToolStripControlHost host = new ToolStripControlHost(Pagination);
            host.Padding = new Padding(0);

            ToolStripDropDown dropdown = new ToolStripDropDown();
            dropdown.Padding = new Padding(0);
            dropdown.Items.Add(host);
            if (this.Items.Count > 0)
            {
                dropdown.Show(this, 0, 3 + this.Height + (this.Items.Count * this.ItemHeight));
            }
        }
    }
}

CtechPagination.cs

using CardData.Ext.Mod.Logger;
using DiscountCard.Ext.Mod.General;
using DiscountCard.View.CustomControl.Pagination;

namespace DiscountCard.View.CustomControl
{
    public partial class CtechPagination : UserControl
    {
        public enum PaginationPosition
        {
            FirstPage,
            PreviousPage,
            NextPage,
            LastPage,
            CurrrentPage
        }

        public CtechPagination()
        {
            InitializeComponent();

            FirstPaginationButton.Click += OnFirstPaginationButton_Click;
            PrevPaginationButton.Click += OnPrevPaginationButton_Click;
            NextPaginationButton.Click += OnNextPaginationButton_Click;
            LastPaginationButton.Click += OnLastPaginationButton_Click;
        }

        public event EventHandler? FirstPaginationButton_Click;
        public event EventHandler? PrevPaginationButton_Click;
        public event EventHandler? NextPaginationButton_Click;
        public event EventHandler? LastPaginationButton_Click;
        protected virtual void OnFirstPaginationButton_Click(object? sender, EventArgs e)
        {
            try
            {
                if (Pages == null)
                {
                    return;
                }
                if (Pages.Count == 0)
                {
                    return;
                }

                PageIndex = 0;

                Page? firstPage = Pages[PageIndex];
                if (firstPage != null)
                {
                    PagesLabel.Text = String.Format("{0:N0} of {1:N0}", firstPage.MinIndex, firstPage.MaxIndex);
                    FirstPage = firstPage;

                    CurrentPage = firstPage;

                    FirstPaginationButton_Click?.Invoke(this, e);
                }
            }
            catch (Exception ex)
            {
                ExLogger.LogException(ex, "");
            }
        }
        protected virtual void OnPrevPaginationButton_Click(object? sender, EventArgs e)
        {
            try
            {
                if (Pages == null)
                {
                    return;
                }
                if (Pages.Count == 0)
                {
                    return;
                }

                --PageIndex;
                if (PageIndex < 0)
                {
                    PageIndex = 0;
                }

                Page? prevPage = Pages[PageIndex];
                if (prevPage != null)
                {
                    PagesLabel.Text = String.Format("{0:N0} of {1:N0}", prevPage.MinIndex, prevPage.MaxIndex);
                    PreviousPage = prevPage;

                    CurrentPage = prevPage;

                    PrevPaginationButton_Click?.Invoke(this, e);
                }
            }
            catch (Exception ex)
            {
                ExLogger.LogException(ex, "");
            }
        }
        protected virtual void OnNextPaginationButton_Click(object? sender, EventArgs e)
        {
            try
            {
                if (Pages == null)
                {
                    return;
                }
                if (Pages.Count == 0)
                {
                    return;
                }

                ++PageIndex;
                if (PageIndex > Pages.Count - 1)
                {
                    PageIndex = Pages.Count - 1;
                }

                Page? nextPage = Pages[PageIndex];
                if (nextPage != null)
                {
                    PagesLabel.Text = String.Format("{0:N0} of {1:N0}", nextPage.MinIndex, nextPage.MaxIndex);
                    NextPage = nextPage;

                    CurrentPage = nextPage;

                    NextPaginationButton_Click?.Invoke(this, e);
                }
            }
            catch (Exception ex)
            {
                ExLogger.LogException(ex, "");
            }
        }
        protected virtual void OnLastPaginationButton_Click(object? sender, EventArgs e)
        {
            try
            {
                if (Pages == null)
                {
                    return;
                }
                if (Pages.Count == 0)
                {
                    return;
                }

                PageIndex = Pages.Count - 1;

                Page? lastPage = Pages[PageIndex

<details>
<summary>英文:</summary>

I want when the button in Pagination is clicked, the dropdown of the Combo Box is still opened, so I can see the result of the pagination in the items of the Combo Box and the dropdown closed when I selected item of Combo Box.

My problem is when I click the buttons in Pagination, the dropdown of the Combo Box closed, so I can&#39;t see the result of the pagination.

How to prevent dropdown of Combo Box collapse before item selected in C# Win Form?

**CtechComboBoxPagination.cs**
    
    using static DiscountCard.View.CustomControl.CtechPagination;
    
    namespace DiscountCard.View.CustomControl
    {
        public partial class CtechComboBoxPagination : ComboBox
        {
            public CtechPagination? Pagination { get; set; }
    
            protected override CreateParams CreateParams
            {
                get
                {
                    CreateParams cp = base.CreateParams;
                    cp.ExStyle |= 0x02000000;  // Turn on WS_EX_COMPOSITED
                    return cp;
                }
            }
    
            public CtechComboBoxPagination()
            {
                InitializeComponent();
    
                DoubleBuffered = true;
                DropDownStyle = ComboBoxStyle.DropDownList;
                DrawMode = DrawMode.OwnerDrawFixed;
                Font = new Font(&quot;Consolas&quot;, 11F, FontStyle.Regular, GraphicsUnit.Point);
    
                Pagination = new CtechPagination();
                Pagination.SetInitialize(Enumerable.Range(0, 100).AsQueryable(), newContent: true, PaginationPosition.LastPage);
                Pagination.FirstPaginationButton_Click += Pagination_FirstPaginationButton_Click;
                Pagination.PrevPaginationButton_Click += Pagination_PrevPaginationButton_Click;
                Pagination.NextPaginationButton_Click += Pagination_NextPaginationButton_Click;
                Pagination.LastPaginationButton_Click += Pagination_LastPaginationButton_Click;
            }
    
            private void Pagination_FirstPaginationButton_Click(object? sender, EventArgs e)
            {
                DroppedDown = true;
            }
            private void Pagination_PrevPaginationButton_Click(object? sender, EventArgs e)
            {
                DroppedDown = true;
            }
            private void Pagination_NextPaginationButton_Click(object? sender, EventArgs e)
            {
                DroppedDown = true;
            }
            private void Pagination_LastPaginationButton_Click(object? sender, EventArgs e)
            {
                DroppedDown = true;
            }
    
            protected override void OnDrawItem(DrawItemEventArgs e)
            {
                e.DrawBackground();
    
                if (e.Index &lt; 0 || e.Index &gt;= Items.Count)
                {
                    return;
                }
                var item = Items[e.Index];
                String? text = item == null ? &quot;(null)&quot; : item.ToString();
    
                TextRenderer.DrawText(e.Graphics, text, e.Font, e.Bounds, e.ForeColor, TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
    
                base.OnDrawItem(e);
            }
    
            protected override void OnDropDown(EventArgs e)
            {
                base.OnDropDown(e);
    
                if (Pagination == null)
                {
                    return;
                }
    
                // for test
                if (Pagination.CurrentPage != null)
                {
                    Items.Clear();
                    for (int i = Pagination.CurrentPage.MinIndex; i &lt;= Pagination.CurrentPage.MaxIndex; i++)
                    {
                        Items.Add(i);
                    }
                }
    
                Pagination.Margin = new Padding(0);
                Pagination.MinimumSize = new Size(this.Width, 30);
    
                ToolStripControlHost host = new ToolStripControlHost(Pagination);
                host.Padding = new Padding(0);
    
                ToolStripDropDown dropdown = new ToolStripDropDown();
                dropdown.Padding = new Padding(0);
                dropdown.Items.Add(host);
                if (this.Items.Count &gt; 0)
                {
                    dropdown.Show(this, 0, 3 + this.Height + (this.Items.Count * this.ItemHeight));
                }
            }
        }
    }
    
    
**CtechPagination.cs**

    
    using CardData.Ext.Mod.Logger;
    using DiscountCard.Ext.Mod.General;
    using DiscountCard.View.CustomControl.Pagination;
    
    namespace DiscountCard.View.CustomControl
    {
    	public partial class CtechPagination : UserControl
    	{
    		public enum PaginationPosition
    		{
    			FirstPage,
    			PreviousPage,
    			NextPage,
    			LastPage,
    			CurrrentPage
    		}
    
    		public CtechPagination()
    		{
    			InitializeComponent();
    
    			FirstPaginationButton.Click += OnFirstPaginationButton_Click;
    			PrevPaginationButton.Click += OnPrevPaginationButton_Click;
    			NextPaginationButton.Click += OnNextPaginationButton_Click;
    			LastPaginationButton.Click += OnLastPaginationButton_Click;
    		}
    
    		public event EventHandler? FirstPaginationButton_Click;
    		public event EventHandler? PrevPaginationButton_Click;
    		public event EventHandler? NextPaginationButton_Click;
    		public event EventHandler? LastPaginationButton_Click;
    		protected virtual void OnFirstPaginationButton_Click(object? sender, EventArgs e)
    		{
    			try
    			{
    				if (Pages == null)
    				{
    					return;
    				}
    				if (Pages.Count == 0)
    				{
    					return;
    				}
    
    				PageIndex = 0;
    
    				Page? firstPage = Pages[PageIndex];
    				if (firstPage != null)
    				{
    					PagesLabel.Text = String.Format(&quot;{0:N0} of {1:N0}&quot;, firstPage.MinIndex, firstPage.MaxIndex);
    					FirstPage = firstPage;
    
    					CurrentPage = firstPage;
    
    					FirstPaginationButton_Click?.Invoke(this, e);
    				}
    			}
    			catch (Exception ex)
    			{
    				ExLogger.LogException(ex, &quot;&quot;);
    			}
    		}
    		protected virtual void OnPrevPaginationButton_Click(object? sender, EventArgs e)
    		{
    			try
    			{
    				if (Pages == null)
    				{
    					return;
    				}
    				if (Pages.Count == 0)
    				{
    					return;
    				}
    
    				--PageIndex;
    				if (PageIndex &lt; 0)
    				{
    					PageIndex = 0;
    				}
    
    				Page? prevPage = Pages[PageIndex];
    				if (prevPage != null)
    				{
    					PagesLabel.Text = String.Format(&quot;{0:N0} of {1:N0}&quot;, prevPage.MinIndex, prevPage.MaxIndex);
    					PreviousPage = prevPage;
    
    					CurrentPage = prevPage;
    
    					PrevPaginationButton_Click?.Invoke(this, e);
    				}
    			}
    			catch (Exception ex)
    			{
    				ExLogger.LogException(ex, &quot;&quot;);
    			}
    		}
    		protected virtual void OnNextPaginationButton_Click(object? sender, EventArgs e)
    		{
    			try
    			{
    				if (Pages == null)
    				{
    					return;
    				}
    				if (Pages.Count == 0)
    				{
    					return;
    				}
    
    				++PageIndex;
    				if (PageIndex &gt; Pages.Count - 1)
    				{
    					PageIndex = Pages.Count - 1;
    				}
    
    				Page? nextPage = Pages[PageIndex];
    				if (nextPage != null)
    				{
    					PagesLabel.Text = String.Format(&quot;{0:N0} of {1:N0}&quot;, nextPage.MinIndex, nextPage.MaxIndex);
    					NextPage = nextPage;
    
    					CurrentPage = nextPage;
    
    					NextPaginationButton_Click?.Invoke(this, e);
    				}
    			}
    			catch (Exception ex)
    			{
    				ExLogger.LogException(ex, &quot;&quot;);
    			}
    		}
    		protected virtual void OnLastPaginationButton_Click(object? sender, EventArgs e)
    		{
    			try
    			{
    				if (Pages == null)
    				{
    					return;
    				}
    				if (Pages.Count == 0)
    				{
    					return;
    				}
    
    				PageIndex = Pages.Count - 1;
    
    				Page? lastPage = Pages[PageIndex];
    				if (lastPage != null)
    				{
    					PagesLabel.Text = String.Format(&quot;{0:N0} of {1:N0}&quot;, lastPage.MinIndex, lastPage.MaxIndex);
    					LastPage = lastPage;
    
    					CurrentPage = lastPage;
    
    					LastPaginationButton_Click?.Invoke(this, e);
    				}
    			}
    			catch (Exception ex)
    			{
    				ExLogger.LogException(ex, &quot;&quot;);
    			}
    		}
    		public void SetInitialize(IQueryable&lt;int&gt; source, bool newContent, PaginationPosition selectedPagination)
    		{
    			PageSize = Common.DEFAULT_PAGE_SIZE;
    
    			TotalCount = source.Count();
    			if (TotalCount &lt;= 0)
    			{
    				return;
    			}
    
    			TotalPages = (int)Math.Ceiling(TotalCount / (double)PageSize);
    			if (TotalPages &lt;= 0)
    			{
    				return;
    			}
    
    			if (newContent)
    			{
    				Pages = new List&lt;Page&gt;();
    				for (int i = 0; i &lt; TotalPages; i++)
    				{
    					IQueryable&lt;int&gt; indexes = (IQueryable&lt;int&gt;)source.Skip(i * PageSize).Take(PageSize);
    					if (indexes != null)
    					{
    						Page page = new Page();
    						page.MinIndex = 1 + indexes.Min();
    						page.MaxIndex = 1 + indexes.Max();
    						Pages.Add(page);
    					}
    				}
    			}
    
    			if (Pages != null)
    			{
    				switch (selectedPagination)
    				{
    					case PaginationPosition.FirstPage:
    						if (newContent)
    						{
    							PageIndex = 0;
    						}
    
    						Page? firstPage = Pages[PageIndex];
    						if (firstPage != null)
    						{
    							PagesLabel.Text = String.Format(&quot;{0:N0} of {1:N0}&quot;, firstPage.MinIndex, firstPage.MaxIndex);
    							FirstPage = firstPage;
    
    							CurrentPage = firstPage;
    						}
    						break;
    
    					case PaginationPosition.PreviousPage:
    						if (newContent)
    						{
    							--PageIndex;
    						}
    						if (PageIndex &lt; 0)
    						{
    							PageIndex = 0;
    						}
    
    						Page? prevPage = Pages[PageIndex];
    						if (prevPage != null)
    						{
    							PagesLabel.Text = String.Format(&quot;{0:N0} of {1:N0}&quot;, prevPage.MinIndex, prevPage.MaxIndex);
    							PreviousPage = prevPage;
    
    							CurrentPage = prevPage;
    						}
    						break;
    
    					case PaginationPosition.NextPage:
    						if (newContent)
    						{
    							++PageIndex;
    						}
    						if (PageIndex &gt; Pages.Count - 1)
    						{
    							PageIndex = Pages.Count - 1;
    						}
    
    						Page? nextPage = Pages[PageIndex];
    						if (nextPage != null)
    						{
    							PagesLabel.Text = String.Format(&quot;{0:N0} of {1:N0}&quot;, nextPage.MinIndex, nextPage.MaxIndex);
    							NextPage = nextPage;
    
    							CurrentPage = nextPage;
    						}
    						break;
    
    					case PaginationPosition.LastPage:
    						if (newContent)
    						{
    							PageIndex = Pages.Count - 1;
    						}
    						if (PageIndex &lt; 0)
    						{
    							PageIndex = 0;
    						}
    
    						Page? lastPage = Pages[PageIndex];
    						if (lastPage != null)
    						{
    							PagesLabel.Text = String.Format(&quot;{0:N0} of {1:N0}&quot;, lastPage.MinIndex, lastPage.MaxIndex);
    							LastPage = lastPage;
    
    							CurrentPage = lastPage;
    						}
    						break;
    
    					case PaginationPosition.CurrrentPage:
    						if (PageIndex &lt; 0)
    						{
    							PageIndex = 0;
    						}
    						if (PageIndex &gt; Pages.Count - 1)
    						{
    							PageIndex = Pages.Count - 1;
    						}
    
    						Page? curentPage = Pages[PageIndex];
    						if (curentPage != null)
    						{
    							PagesLabel.Text = String.Format(&quot;{0:N0} of {1:N0}&quot;, curentPage.MinIndex, curentPage.MaxIndex);
    							CurrentPage = curentPage;
    						}
    						break;
    				}
    			}
    		}
    
    		public int PageIndex { get; private set; }
    		public int PageSize { get; private set; }
    		public int TotalCount { get; private set; }
    		public int TotalPages { get; private set; }
    		public List&lt;Page&gt;? Pages { get; private set; }
    
    		public Page? CurrentPage { get; private set; }
    		public Page? FirstPage { get; private set; }
    		public Page? PreviousPage { get; private set; }
    		public Page? NextPage { get; private set; }
    		public Page? LastPage { get; private set; }
    
    	}
    }
    
    
**CtechPagination.Designer.cs**

    
    namespace DiscountCard.View.CustomControl
    {
        partial class CtechPagination
        {
            /// &lt;summary&gt; 
            /// Required designer variable.
            /// &lt;/summary&gt;
            private System.ComponentModel.IContainer components = null;
    
            /// &lt;summary&gt; 
            /// Clean up any resources being used.
            /// &lt;/summary&gt;
            /// &lt;param name=&quot;disposing&quot;&gt;true if managed resources should be disposed; otherwise, false.&lt;/param&gt;
            protected override void Dispose(bool disposing)
            {
                if (disposing &amp;&amp; (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }
    
            #region Component Designer generated code
    
            /// &lt;summary&gt; 
            /// Required method for Designer support - do not modify 
            /// the contents of this method with the code editor.
            /// &lt;/summary&gt;
            private void InitializeComponent()
            {
                this.PaginationTableLayoutPanel = new DiscountCard.View.CustomControl.CtechTableLayoutPanel();
                this.FirstPaginationButton = new System.Windows.Forms.Button();
                this.PrevPaginationButton = new System.Windows.Forms.Button();
                this.NextPaginationButton = new System.Windows.Forms.Button();
                this.LastPaginationButton = new System.Windows.Forms.Button();
                this.PagesLabel = new System.Windows.Forms.Label();
                this.PaginationTableLayoutPanel.SuspendLayout();
                this.SuspendLayout();
                // 
                // PaginationTableLayoutPanel
                // 
                this.PaginationTableLayoutPanel.ColumnCount = 9;
                this.PaginationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 5F));
                this.PaginationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 50F));
                this.PaginationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 5F));
                this.PaginationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 50F));
                this.PaginationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
                this.PaginationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 50F));
                this.PaginationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 5F));
                this.PaginationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 50F));
                this.PaginationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 5F));
                this.PaginationTableLayoutPanel.Controls.Add(this.FirstPaginationButton, 1, 0);
                this.PaginationTableLayoutPanel.Controls.Add(this.PrevPaginationButton, 3, 0);
                this.PaginationTableLayoutPanel.Controls.Add(this.NextPaginationButton, 5, 0);
                this.PaginationTableLayoutPanel.Controls.Add(this.LastPaginationButton, 7, 0);
                this.PaginationTableLayoutPanel.Controls.Add(this.PagesLabel, 4, 0);
                this.PaginationTableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
                this.PaginationTableLayoutPanel.Location = new System.Drawing.Point(0, 0);
                this.PaginationTableLayoutPanel.Name = &quot;PaginationTableLayoutPanel&quot;;
                this.PaginationTableLayoutPanel.RowCount = 1;
                this.PaginationTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
                this.PaginationTableLayoutPanel.Size = new System.Drawing.Size(816, 30);
                this.PaginationTableLayoutPanel.TabIndex = 0;
                // 
                // FirstPaginationButton
                // 
                this.FirstPaginationButton.Dock = System.Windows.Forms.DockStyle.Fill;
                this.FirstPaginationButton.Font = new System.Drawing.Font(&quot;Segoe UI&quot;, 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
                this.FirstPaginationButton.Location = new System.Drawing.Point(8, 3);
                this.FirstPaginationButton.Name = &quot;FirstPaginationButton&quot;;
                this.FirstPaginationButton.Size = new System.Drawing.Size(44, 24);
                this.FirstPaginationButton.TabIndex = 0;
                this.FirstPaginationButton.Text = &quot;⟨⟨&quot;;
                this.FirstPaginationButton.UseVisualStyleBackColor = true;
                // 
                // PrevPaginationButton
                // 
                this.PrevPaginationButton.Dock = System.Windows.Forms.DockStyle.Fill;
                this.PrevPaginationButton.Font = new System.Drawing.Font(&quot;Segoe UI&quot;, 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
                this.PrevPaginationButton.Location = new System.Drawing.Point(63, 3);
                this.PrevPaginationButton.Name = &quot;PrevPaginationButton&quot;;
                this.PrevPaginationButton.Size = new System.Drawing.Size(44, 24);
                this.PrevPaginationButton.TabIndex = 1;
                this.PrevPaginationButton.Text = &quot;&quot;;
                this.PrevPaginationButton.UseVisualStyleBackColor = true;
                // 
                // NextPaginationButton
                // 
                this.NextPaginationButton.Dock = System.Windows.Forms.DockStyle.Fill;
                this.NextPaginationButton.Font = new System.Drawing.Font(&quot;Segoe UI&quot;, 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
                this.NextPaginationButton.Location = new System.Drawing.Point(709, 3);
                this.NextPaginationButton.Name = &quot;NextPaginationButton&quot;;
                this.NextPaginationButton.Size = new System.Drawing.Size(44, 24);
                this.NextPaginationButton.TabIndex = 2;
                this.NextPaginationButton.Text = &quot;&quot;;
                this.NextPaginationButton.UseVisualStyleBackColor = true;
                // 
                // LastPaginationButton
                // 
                this.LastPaginationButton.Dock = System.Windows.Forms.DockStyle.Fill;
                this.LastPaginationButton.Font = new System.Drawing.Font(&quot;Segoe UI&quot;, 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
                this.LastPaginationButton.Location = new System.Drawing.Point(764, 3);
                this.LastPaginationButton.Name = &quot;LastPaginationButton&quot;;
                this.LastPaginationButton.Size = new System.Drawing.Size(44, 24);
                this.LastPaginationButton.TabIndex = 3;
                this.LastPaginationButton.Text = &quot;⟩⟩&quot;;
                this.LastPaginationButton.UseVisualStyleBackColor = true;
                // 
                // PagesLabel
                // 
                this.PagesLabel.AutoSize = true;
                this.PagesLabel.Dock = System.Windows.Forms.DockStyle.Fill;
                this.PagesLabel.Location = new System.Drawing.Point(113, 0);
                this.PagesLabel.Name = &quot;PagesLabel&quot;;
                this.PagesLabel.Size = new System.Drawing.Size(590, 30);
                this.PagesLabel.TabIndex = 4;
                this.PagesLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
                // 
                // CtechPagination
                // 
                this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.Controls.Add(this.PaginationTableLayoutPanel);
                this.Margin = new System.Windows.Forms.Padding(0);
                this.Name = &quot;CtechPagination&quot;;
                this.Size = new System.Drawing.Size(816, 30);
                this.PaginationTableLayoutPanel.ResumeLayout(false);
                this.PaginationTableLayoutPanel.PerformLayout();
                this.ResumeLayout(false);
    
            }
    
            #endregion
    
            private CtechTableLayoutPanel PaginationTableLayoutPanel;
            private Button FirstPaginationButton;
            private Button PrevPaginationButton;
            private Button NextPaginationButton;
            private Button LastPaginationButton;
            private Label PagesLabel;
        }
    }

[![enter image description here](https://i.stack.imgur.com/bYQcK.png)](https://i.stack.imgur.com/bYQcK.png)

[![enter image description here](https://i.stack.imgur.com/a7Xhc.png)](https://i.stack.imgur.com/a7Xhc.png)





</details>


# 答案1
**得分**: 1

根据我的理解,您已经为分页制作了一个`UserControl`,当单击导航按钮之一时,会导致不希望的下拉关闭。

我能够重现您描述的行为,然后通过为用户控件实施[IMessageFilter](https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.imessagefilter)来拦截鼠标事件并将它们标记为“已处理”来抑制它。

```csharp
public partial class Pagination : UserControl, IMessageFilter
{
    public Pagination()
    {
        InitializeComponent();
        Application.AddMessageFilter(this);
        Disposed += (sender, e) => Application.RemoveMessageFilter(this);
        PagesLabel.Text = $"Page {Page} of {Pages}";
    }

    const int WM_LBUTTONDOWN = 0x0201;
    const int WM_LBUTTONUP = 0x0202;
    public bool PreFilterMessage(ref Message m)
    {
        var client = PointToClient(MousePosition);
        switch (m.Msg)
        {
            case WM_LBUTTONDOWN:
                if (ClientRectangle.Contains(client))
                {
                    IterateControlTree((control) => hitTest(control, client));
                    return true;
                }
                break;
            case WM_LBUTTONUP:
                if (ClientRectangle.Contains(client))
                {
                    return true;
                }
                break;
        }
        return false;
    }
    .
    .
    .
}

要清楚,这意味着也不会发生Button.Click事件!因此,有必要迭代用户控件的Control树,以对其包含的按钮控件执行命中测试。

bool IterateControlTree(Func<Control, bool> action, Control control = null)
{
    if (control == null) control = this;
    if (action(control)) return true;
    foreach (Control child in control.Controls)
    {
        if (IterateControlTree(action, child))
        {
            return true;
        }
    }
    return false;
}

例如,检测在其中一个按钮的客户端矩形内的点击可以修改Page属性,从而触发组合框对事件的响应。

private bool hitTest(Control control, Point client)
{
    if (control.Bounds.Contains(client))
    {
        switch (control.Name)
        {
            case nameof(FirstPaginationButton): Page = 1; return true;
            case nameof(PrevPaginationButton): Page--; return true;
            case nameof(NextPaginationButton): Page++; return true;
            case nameof(LastPaginationButton): Page = Pages; return true;
            default: break;
        }
    }
    return false;
}

如果有帮助,可以随时浏览或克隆我编写的代码来测试这个答案。

英文:

As I understand it, you've made a UserControl for the pagination and when you click on one of the nav buttons it results in an unwanted close of the drop down.

阻止组合框在选择项目之前折叠下拉菜单

I was able to reproduce the behavior you're describing and then was able to suppress it by implementing IMessageFilter for the user control in order to intercept the mouse events and mark them as "handled" in the filter (if they occur inside the client rectangle of the UC).

阻止组合框在选择项目之前折叠下拉菜单

public partial class Pagination : UserControl, IMessageFilter
{
public Pagination()
{
InitializeComponent();
Application.AddMessageFilter(this);
Disposed += (sender, e) =&gt;Application.RemoveMessageFilter(this);
PagesLabel.Text = $&quot;Page {Page} of {Pages}&quot;;
}
const int WM_LBUTTONDOWN = 0x0201;
const int WM_LBUTTONUP = 0x0202;
public bool PreFilterMessage(ref Message m)
{
var client = PointToClient(MousePosition);
switch (m.Msg)
{
case WM_LBUTTONDOWN:
if (ClientRectangle.Contains(client))
{
IterateControlTree((control) =&gt; hitTest(control, client));
return true;
}
break;
case WM_LBUTTONUP:
if(ClientRectangle.Contains(client))
{
return true;
}
break;
}
return false;
}
.
.
.
}

To be clear, this means no Button.Click events are going to take place either! For this reason it's necessary to iterate the Control tree of the user control to perform a hit test on the button controls it contains.

bool IterateControlTree(Func&lt;Control, bool&gt; action, Control control = null)
{
if (control == null) control = this;
if(action(control)) return true;
foreach (Control child in control.Controls)
{
if(IterateControlTree(action, child))
{
return true;
}
}
return false;
}

For example, detecting a click in the client rectangle of one of the buttons could modify a Page property which in turn fires an event for the combo box to react.

private bool hitTest(Control control, Point client)
{
if (control.Bounds.Contains(client))
{
switch (control.Name)
{
case nameof(FirstPaginationButton): Page = 1; return true;
case nameof(PrevPaginationButton): Page --; return true;
case nameof(NextPaginationButton): Page ++; return true;
case nameof(LastPaginationButton): Page = Pages; return true;
default: break;
}
}
return false;
}

Feel free to browse or clone the code I wrote to test this answer if that would be helpful.

huangapple
  • 本文由 发表于 2023年2月18日 22:43:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75494092.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定