作業中の小さなアプリケーションでCheckedListBoxコントロールを使用しています。これは優れたコントロールですが、1つ気になります。チェックボックスを実際にチェックしたときにのみアイテムをチェックするようにプロパティを設定できません。これを克服するための最良の方法は何ですか?チェックボックスの左側からの相対的なマウスクリックの位置を取得することを考えていました。これは部分的には機能しますが、空のスペースをクリックすると、現在選択されている項目がチェックされます。これに関するアイデアはありますか?
6 に答える
このスレッドが少し古いことは知っていますが、別の解決策を提供することは問題ではないと思います。
private void checkedListBox1_MouseClick(object sender, MouseEventArgs e)
{
if ((e.Button == MouseButtons.Left) & (e.X > 13))
{
this.checkedListBox1.SetItemChecked(this.checkedListBox1.SelectedIndex, !this.checkedListBox1.GetItemChecked(this.checkedListBox1.SelectedIndex));
}
}
(の値を使用CheckOnClick = True
)。
長方形でそれを使用することもできますが、なぜそれをより複雑にする必要があります。
CheckedListBox.MouseDown
まあ、それはかなり醜いですが、次のCheckedListBox.ItemCheck
ようにフックすることで、アイテムの長方形に対するマウスのヒット座標を計算できます
/// <summary>
/// In order to control itemcheck changes (blinds double clicking, among other things)
/// </summary>
bool AuthorizeCheck { get; set; }
private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
if(!AuthorizeCheck)
e.NewValue = e.CurrentValue; //check state change was not through authorized actions
}
private void checkedListBox1_MouseDown(object sender, MouseEventArgs e)
{
Point loc = this.checkedListBox1.PointToClient(Cursor.Position);
for (int i = 0; i < this.checkedListBox1.Items.Count; i++)
{
Rectangle rec = this.checkedListBox1.GetItemRectangle(i);
rec.Width = 16; //checkbox itself has a default width of about 16 pixels
if (rec.Contains(loc))
{
AuthorizeCheck = true;
bool newValue = !this.checkedListBox1.GetItemChecked(i);
this.checkedListBox1.SetItemChecked(i, newValue);//check
AuthorizeCheck = false;
return;
}
}
}
もう1つの解決策は、Treeviewを使用することです。
CheckBoxesをtrueに、ShowLinesをfalseに、ShowPlusMinusをfalseに設定すると、基本的にCheckedListBoxと同じものになります。項目は、実際のチェックボックスがクリックされたときにのみチェックされます。
CheckedListBoxははるかに単純ですが、TreeViewには、プログラムにより適している可能性のある多くのオプションが用意されています。
私はこのプロパティをうまく使用しました:
CheckedBoxList.CheckOnClick
CheckedListBoxのチェックボックスのテキストは、デフォルトでレンダリングされ、チェックボックス入力の後にHTMLラベルを配置し、ラベルの「for」属性をチェックボックスのIDに設定します。
ラベルが「対象」の要素を示している場合、そのラベルをクリックすると、ブラウザにその要素に焦点を合わせるように指示されます。これは、表示されている要素です。
2つのオプションは、リストが静的である場合は個別のCheckBoxコントロールとテキスト(CheckBoxのTextプロパティとしてではなく、CheckBoxListと同じことを行うため)を使用して独自のリストをレンダリングするか、リストが静的である場合はリピーターのようなものを使用することです。動的。
これを試して。iLastIndexClickedをフォームレベルのint変数として宣言します。
private void chklst_MouseClick(object sender, MouseEventArgs e)
{
Point p = chklst.PointToClient(MousePosition);
int i = chklst.IndexFromPoint(p);
if (p.X > 15) { return; } // Body click.
if (chklst.CheckedIndices.Contains(i)){ return; } // If already has focus click anywhere works right.
if (iLastIndexClicked == i) { return; } // native code will check/uncheck
chklst.SetItemChecked(i, true);
iLastIndexClicked = i;
}
ユーザーがチェックリストの左端の15ピクセル(チェックボックス領域)をクリックしたかどうかを確認するだけで、現在選択されている項目を再チェックする場合を除いて、常に機能します。最後のインデックスを保存して変更せずに終了すると、ネイティブコードがそれを適切に処理できるようになります。その場合、チェック済みに設定しようとするとオンになり、「ItemCheck」コードの実行時にオフに戻ります。