英文:
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'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];
if (lastPage != null)
{
PagesLabel.Text = String.Format("{0:N0} of {1:N0}", lastPage.MinIndex, lastPage.MaxIndex);
LastPage = lastPage;
CurrentPage = lastPage;
LastPaginationButton_Click?.Invoke(this, e);
}
}
catch (Exception ex)
{
ExLogger.LogException(ex, "");
}
}
public void SetInitialize(IQueryable<int> source, bool newContent, PaginationPosition selectedPagination)
{
PageSize = Common.DEFAULT_PAGE_SIZE;
TotalCount = source.Count();
if (TotalCount <= 0)
{
return;
}
TotalPages = (int)Math.Ceiling(TotalCount / (double)PageSize);
if (TotalPages <= 0)
{
return;
}
if (newContent)
{
Pages = new List<Page>();
for (int i = 0; i < TotalPages; i++)
{
IQueryable<int> indexes = (IQueryable<int>)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("{0:N0} of {1:N0}", firstPage.MinIndex, firstPage.MaxIndex);
FirstPage = firstPage;
CurrentPage = firstPage;
}
break;
case PaginationPosition.PreviousPage:
if (newContent)
{
--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;
}
break;
case PaginationPosition.NextPage:
if (newContent)
{
++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;
}
break;
case PaginationPosition.LastPage:
if (newContent)
{
PageIndex = Pages.Count - 1;
}
if (PageIndex < 0)
{
PageIndex = 0;
}
Page? lastPage = Pages[PageIndex];
if (lastPage != null)
{
PagesLabel.Text = String.Format("{0:N0} of {1:N0}", lastPage.MinIndex, lastPage.MaxIndex);
LastPage = lastPage;
CurrentPage = lastPage;
}
break;
case PaginationPosition.CurrrentPage:
if (PageIndex < 0)
{
PageIndex = 0;
}
if (PageIndex > Pages.Count - 1)
{
PageIndex = Pages.Count - 1;
}
Page? curentPage = Pages[PageIndex];
if (curentPage != null)
{
PagesLabel.Text = String.Format("{0:N0} of {1:N0}", 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<Page>? 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
{
/// <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 Component 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.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 = "PaginationTableLayoutPanel";
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("Segoe UI", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.FirstPaginationButton.Location = new System.Drawing.Point(8, 3);
this.FirstPaginationButton.Name = "FirstPaginationButton";
this.FirstPaginationButton.Size = new System.Drawing.Size(44, 24);
this.FirstPaginationButton.TabIndex = 0;
this.FirstPaginationButton.Text = "⟨⟨";
this.FirstPaginationButton.UseVisualStyleBackColor = true;
//
// PrevPaginationButton
//
this.PrevPaginationButton.Dock = System.Windows.Forms.DockStyle.Fill;
this.PrevPaginationButton.Font = new System.Drawing.Font("Segoe UI", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.PrevPaginationButton.Location = new System.Drawing.Point(63, 3);
this.PrevPaginationButton.Name = "PrevPaginationButton";
this.PrevPaginationButton.Size = new System.Drawing.Size(44, 24);
this.PrevPaginationButton.TabIndex = 1;
this.PrevPaginationButton.Text = "⟨";
this.PrevPaginationButton.UseVisualStyleBackColor = true;
//
// NextPaginationButton
//
this.NextPaginationButton.Dock = System.Windows.Forms.DockStyle.Fill;
this.NextPaginationButton.Font = new System.Drawing.Font("Segoe UI", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.NextPaginationButton.Location = new System.Drawing.Point(709, 3);
this.NextPaginationButton.Name = "NextPaginationButton";
this.NextPaginationButton.Size = new System.Drawing.Size(44, 24);
this.NextPaginationButton.TabIndex = 2;
this.NextPaginationButton.Text = "⟩";
this.NextPaginationButton.UseVisualStyleBackColor = true;
//
// LastPaginationButton
//
this.LastPaginationButton.Dock = System.Windows.Forms.DockStyle.Fill;
this.LastPaginationButton.Font = new System.Drawing.Font("Segoe UI", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.LastPaginationButton.Location = new System.Drawing.Point(764, 3);
this.LastPaginationButton.Name = "LastPaginationButton";
this.LastPaginationButton.Size = new System.Drawing.Size(44, 24);
this.LastPaginationButton.TabIndex = 3;
this.LastPaginationButton.Text = "⟩⟩";
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 = "PagesLabel";
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 = "CtechPagination";
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) =>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;
}
.
.
.
}
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<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;
}
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论