私はあなたにいくつかの提案があります。回答の下部に、提案を示すコードを含めました。
提案1:UCでのMouseClickの修正
UserControl(UC)にMouseClickイベントを登録する場合、ラベルなどのUserControlに配置するコントロールではなく、UserControl自体に対して登録します。クリックした場合これらの子コントロールの1つは、基になるUCによってクリックが「表示」されないように制御します。
これを修正するには、すべての子コントロールのMouseClickイベントを登録します。UserControl自体に使用しているのと同じMouseClickイベントハンドラーを登録することもできます。
提案2:UCのBorderStyle
を設定するUCを設定するためのコードをBorderStyle
UC自体に移動します。IsSelected
UCが選択されたときにtrueに設定されるパブリックプロパティを作成します。BorderStyle
プロパティのセッターで、プロパティの値に応じてUCのプロパティを更新します。
UCのプロパティを公開する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);
}
提案3:UCのグループでの選択の管理
ユーザーがクリックする(つまり選択する)ものを除いて、グループ内のすべてのUCの選択を解除する場合は、UCがクリックしました。このイベントのハンドラーはIsSelected
、セット内のすべてのUC(Form、FlowLayoutPanelなどのコンテナータイプコントロールなど)に対して明示的にfalseに設定され、クリックされたUCのMouseClickハンドラーは、クリックされたUCをに設定しますIsSelected
。本当。
UCのグループを管理する別のUserControlタイプを作成することを検討する価値があります。この新しいUserControlは、UCのセットの作成と状態管理のためのコードをカプセル化でき、他のプロジェクトでのUCの使用を容易にするだけでなく、UCをホストするフォームのコードを少しクリーンに保ちます。
私の提案ごとに一連のばらばらのコードスニペットを含めるのではなく、私が話していることを再現できるようにするための最小限のコードであると私が望んでいるものを含めると思いました。
新しいVisualStudioWinformプロジェクトを作成し、クラスに次を使用します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;
}
}
}
}
次に、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;
}
}
}