I have set up UserControls in a FlowPanelLayout with the help in this question:
For Each DataTable Add UserControl to FlowLayoutPanel
I am now trying to implement a click event which allows me to put a border around the UserControl that has been selected. I have done this:
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;
}
My issue is that it only works when I click in a white space in the UserControl but not when the user clicks on the two labels or image. How do I make it work for all child objects too?
Also, how can I then use the selected UserControl to do other things like open a form which shows all the details for that selected user?
I have a few suggestions for you. At the bottom of my response I included code that demonstrates my suggestions.
Suggestion 1: Fixing MouseClick in your UC
When you register the MouseClick event for a UserControl (UC) you’re doing so for the UserControl itself, not for any controls that you place on the UserControl such as your Labels, etc. If you click one of these child controls the click won’t be ‘seen’ by the underlying UC.
To fix this register the MouseClick event for all your child controls; you can even register the same MouseClick event handler you have for the UserControl itself.
Suggestion 2: Setting your UC’s BorderStyle
I’d move your code for setting the UC’s
BorderStyleinto the UC itself. Create public propertyIsSelectedthat’s set to true when the UC is selected. In the property’s setter update the UC’sBorderStyleproperty depending on the value of the property.Exposing an
IsSelectedproperty for your UC can be handy: you can query a group of these UCs to see which ones are selected rather than trying to track this status outside of the control like through a Form-level variable.Edit in response to your comment:
Here’s an example of how you might query the UCs in a FlowLayoutPanel to see if any are selected and if one is found how you might take some action. In this case the action is to call an
EditUsermethod that takes as parameters values you get from properties in the selected UC:Suggestion 3: Managing selection in a group of your UCs
If you want to unselect all UCs in a group except for the one that the user clicks (i.e. selects) you’ll need to create an event in your UC that fires when a UC is clicked. The handler for this event explicitly sets
IsSelectedto false for all UCs in a set (such as in a container type control such as a Form, FlowLayoutPanel, etc.), the MouseClick handler in the UC that was clicked will then set the clicked UC’sIsSelectedto true.It’s worth considering creating another UserControl type that manages a group of your UCs. This new UserControl can encapsulate the code for the creation and state management of sets of your UC and would faciliate using your UCs in other projects as well as keeping the code of Forms hosting your UCs a bit cleaner.
I figured that rather than include a series of disjointed code snippets for each of my suggestions I’d include what I’m hoping is the minimum amount of code to allow you to reproduce what I’m talking about.
Create a new Visual Studio Winform project and use the following for class
Form1:Next add a UserControl to the project. Keep the name
UserControl1and add a couple Labels and a PictureBox. Use this code for classUserControl1: