hsh*_*hah 3 c# select user-controls flowlayoutpanel
我在FlowPanelLayout中设置了UserControls,并在此问题中提供了帮助: For Each DataTable将UserControl添加到FlowLayoutPanel
我现在正在尝试实现一个click事件,它允许我在已选择的UserControl周围放置一个边框.我这样做了:
private void User_Load(object sender, EventArgs e)
{
flowlayoutpanelUsers.HorizontalScroll.Visible = false;
// Load and Sort Users DataTable
DataTable datatableUsers = UserMethods.GetUsers().Tables["Users"];
datatableUsers.DefaultView.Sort = "Name";
DataView dataviewUsers = datatableUsers.DefaultView;
// Loop Through Rows and Add UsersGrid to FlowLayoutPael
foreach (DataRowView datarowviewUsers in dataviewUsers)
{
var UsersGrid = new UsersGrid
{
Username = datarowviewUsers["Username"].ToString(),
User = datarowviewUsers["Name"].ToString(),
Admin = datarowviewUsers["Administrator"].ToString(),
};
flowlayoutpanelUsers.Controls.Add(UsersGrid);
UsersGrid.MouseClick += new MouseEventHandler(user_click);
}
}
private UsersGrid selectedUser;
void user_click(object sender, EventArgs e)
{
if (selectedUser != null)
selectedUser.BorderStyle = BorderStyle.None;
selectedUser = (UsersGrid)sender;
selectedUser.BorderStyle = BorderStyle.FixedSingle;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是它只有在我点击UserControl中的空白区域时才有效,但是当用户点击两个标签或图像时却无效.如何使它适用于所有子对象?
另外,如何使用选定的UserControl执行其他操作,例如打开一个显示所选用户的所有详细信息的表单?
我有一些建议给你.在我的回复的底部,我包含了演示我的建议的代码.
建议1:在您的UC中修复MouseClick
当您为UserControl(UC)注册MouseClick事件时,您正在为UserControl本身注册,而不是您在UserControl上放置的任何控件,例如您的标签等.如果您单击其中一个子控件不会被底层UC"看到".
要修复此寄存器,请为所有子控件修复MouseClick事件; 您甚至可以为UserControl本身注册相同的MouseClick事件处理程序.
建议2:设置UC的BorderStyle
我会移动您的代码以将UC设置BorderStyle为UC本身.创建IsSelected选择UC时设置为true的公共属性.在酒店的setter更新UC的BorderStyle财产取决于财产的价值.
IsSelected为您的UC 公开属性可能很方便:您可以查询这些UC中的一组以查看选择了哪些,而不是像通过表单级变量那样尝试在控件之外跟踪此状态.
编辑以响应您的评论:
这是一个示例,说明如何在FlowLayoutPanel中查询UC以查看是否有任何选定,以及是否找到了如何采取某些操作.在这种情况下,操作是调用一个EditUser方法,该方法将从所选UC中的属性获取的参数值:
var selectedUC = flowLayoutPanel.Controls.Cast<UserControl1>().FirstOrDefault(uc => uc.IsSelected);
if (selectedUC != null) {
// Use the properties of the UC found to be selected as parameters is method EditUser.
EditUser(selectedUC.Name, selectedUC.Username, selectedUC.Administrator);
}
Run Code Online (Sandbox Code Playgroud)
建议3:管理您的UC组中的选择
如果您想要取消选择组中的所有UC(用户单击的那个除了(即选择)),您需要在UC中创建一个事件,当UC是点击.对于集合IsSelected中的所有UC,此事件的处理程序显式设置为false(例如在容器类型控件中,例如Form,FlowLayoutPanel等),单击UC中的MouseClick处理程序将单击的UC设置IsSelected为真正.
值得考虑创建另一个管理一组UC的UserControl类型.这个新的UserControl可以封装代码,用于创建和管理您的UC集合,并可以在其他项目中使用您的UC,以及保持托管您的UC的表单代码更清洁.
我认为,不是为我的每个建议都包含一系列脱节的代码片段,而是包括我希望的最小代码量,以便让你重现我正在谈论的内容.
创建一个新的Visual Studio Winform项目并在课程中使用以下内容Form1:
public partial class Form1 : Form
{
public Form1() {
InitializeComponent();
flowLayoutPanel = new FlowLayoutPanel {
Dock = DockStyle.Fill,
};
this.Controls.Add(flowLayoutPanel);
// Add several sample UCs.
for (int i = 0; i < 10; i++) {
var uc = new UserControl1();
uc.WasClicked += UsersGrid_WasClicked;
flowLayoutPanel.Controls.Add(uc);
}
}
FlowLayoutPanel flowLayoutPanel;
// Event handler for when MouseClick is raised in a UserControl.
void UsersGrid_WasClicked(object sender, EventArgs e) {
// Set IsSelected for all UCs in the FlowLayoutPanel to false.
foreach (Control c in flowLayoutPanel.Controls) {
if (c is UserControl1) {
((UserControl1)c).IsSelected = false;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
接下来,将UserControl添加到项目中.保留名称UserControl1并添加几个标签和PictureBox.在课堂上使用此代码UserControl1:
public partial class UserControl1 : UserControl
{
public UserControl1() {
InitializeComponent();
this.Load += UsersGrid_Load;
}
// Event fires when the MouseClick event fires for the UC or any of its child controls.
public event EventHandler<EventArgs> WasClicked;
private void UsersGrid_Load(object sender, EventArgs e) {
// Register the MouseClick event with the UC's surface.
this.MouseClick += Control_MouseClick;
// Register MouseClick with all child controls.
foreach (Control control in Controls) {
control.MouseClick += Control_MouseClick;
}
}
private void Control_MouseClick(object sender, MouseEventArgs e) {
var wasClicked = WasClicked;
if (wasClicked != null) {
WasClicked(this, EventArgs.Empty);
}
// Select this UC on click.
IsSelected = true;
}
private bool _isSelected;
public bool IsSelected {
get { return _isSelected; }
set {
_isSelected = value;
this.BorderStyle = IsSelected ? BorderStyle.Fixed3D : BorderStyle.None;
}
}
}
Run Code Online (Sandbox Code Playgroud)