トップ回答者
ListViewのDetails表示のFullRowSelectで複数選択時のチェックボックスの挙動

質問
-
お世話になっております。
今回初めて投稿させていただきます。
件名の件なのですが、下記コード(新しいプロジェクト→Windowsアプリケーション→Form1.cs)において実行すると、
「あ」をクリックして次にshift(Ctrl)を押しながら「お」を押す時と
「あ」をクリックして次にshift(Ctrl)を押しながら「こ」or「そ」を押す時とで
チェックボックスの挙動が違うのですが、これはこういう仕様なのでしょうか?
私は複数選択しただけでチェックボックスのチェックを付けたりはずしたりしたくないのですが、
何か方法はないものでしょうか?
-----以下コード-----
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace WindowsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); ListView lv = new ListView(); lv.View = View.Details; ColumnHeader ch1 = new ColumnHeader(); ch1.Text = "あ行"; ch1.Width = 100; ColumnHeader ch2 = new ColumnHeader(); ch2.Text = "か行"; ch2.Width = 100; ColumnHeader ch3 = new ColumnHeader(); ch3.Text = "さ行"; ch3.Width = 100; lv.Columns.AddRange(new ColumnHeader[] { ch1, ch2, ch3 }); ListViewItem lvi1 = new ListViewItem(new string[] { "あ", "か", "さ" }); ListViewItem lvi2 = new ListViewItem(new string[] { "い", "き", "し" }); ListViewItem lvi3 = new ListViewItem(new string[] { "う", "く", "す" }); ListViewItem lvi4 = new ListViewItem(new string[] { "え", "け", "せ" }); ListViewItem lvi5 = new ListViewItem(new string[] { "お", "こ", "そ" }); lv.Items.AddRange(new ListViewItem[] { lvi1, lvi2, lvi3, lvi4, lvi5 }); lv.CheckBoxes = true; lv.Dock = DockStyle.Fill; lv.FullRowSelect = true; this.Controls.Add(lv); } } }
回答
-
かなり以前(2002年ごろ?)からある問題ですが、未だに未解決のようですね。
ListView with multiple columns checks the CheckBoxes on multiselection
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=116181
★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/- 回答としてマーク BlackTomato 2009年2月9日 2:43
すべての返信
-
かなり以前(2002年ごろ?)からある問題ですが、未だに未解決のようですね。
ListView with multiple columns checks the CheckBoxes on multiselection
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=116181
★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/- 回答としてマーク BlackTomato 2009年2月9日 2:43
-
MouseDownとItemCheckの間にItemSelectionChangedイベントがあったのでちょっとやってみました。
これでどうでしょう。
-----以下コード----
public class MyListView : System.Windows.Forms.ListView { private bool _checkEnable = true; private bool _onMouseDown = false; protected override void OnMouseDown ( System.Windows.Forms.MouseEventArgs e ) { // マウスダウンフラグOn this._onMouseDown = true; base.OnMouseDown( e ); } protected override void OnItemSelectionChanged ( System.Windows.Forms.ListViewItemSelectionChangedEventArgs e ) { if ( true == this._onMouseDown ) { // チェック状態変更禁止フラグOn this._checkEnable = false; } base.OnItemSelectionChanged( e ); } protected override void OnItemCheck ( System.Windows.Forms.ItemCheckEventArgs ice ) { if ( false == this._checkEnable ) { // チェック状態変更イベントキャンセル ice.NewValue = ice.CurrentValue; return; } base.OnItemCheck( ice ); } protected override void OnMouseUp ( System.Windows.Forms.MouseEventArgs e ) { // フラグOff this._checkEnable = true; this._onMouseDown = false; base.OnMouseUp( e ); } } - 回答の候補に設定 BlackTomato2 2009年3月12日 2:46
-
最終的なソースはこうなりました。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace WindowsApplication1 { public partial class Form1 : Form { MyListView lv; public Form1() { InitializeComponent(); lv = new MyListView(); lv.View = View.Details; ColumnHeader ch1 = new ColumnHeader(); ch1.Text = "あ行"; ch1.Width = 100; ColumnHeader ch2 = new ColumnHeader(); ch2.Text = "か行"; ch2.Width = 100; ColumnHeader ch3 = new ColumnHeader(); ch3.Text = "さ行"; ch3.Width = 100; lv.Columns.AddRange(new ColumnHeader[] { ch1, ch2, ch3 }); ListViewItem lvi1 = new ListViewItem(new string[] { "あ", "か", "さ" }); ListViewItem lvi2 = new ListViewItem(new string[] { "い", "き", "し" }); ListViewItem lvi3 = new ListViewItem(new string[] { "う", "く", "す" }); ListViewItem lvi4 = new ListViewItem(new string[] { "え", "け", "せ" }); ListViewItem lvi5 = new ListViewItem(new string[] { "お", "こ", "そ" }); lv.Items.AddRange(new ListViewItem[] { lvi1, lvi2, lvi3, lvi4, lvi5 }); lv.CheckBoxes = true; lv.Dock = DockStyle.Fill; lv.FullRowSelect = true; ContextMenu cm = new ContextMenu(); MenuItem mi1 = new MenuItem("check"); mi1.Click += new EventHandler(mi1_Click); MenuItem mi2 = new MenuItem("uncheck"); mi2.Click += new EventHandler(mi2_Click); cm.MenuItems.Add(mi1); cm.MenuItems.Add(mi2); lv.ContextMenu = cm; this.Controls.Add(lv); } void mi1_Click(object sender, EventArgs e) { lv.MenuCheck = true; foreach (ListViewItem lvi in lv.SelectedItems) { lvi.Checked = true; } lv.MenuCheck = false; } void mi2_Click(object sender, EventArgs e) { lv.MenuCheck = true; foreach (ListViewItem lvi in lv.SelectedItems) { lvi.Checked = false; } lv.MenuCheck = false; } } public class MyListView : System.Windows.Forms.ListView { private bool _checkEnable = true; private bool _onMouseDown = false; private bool _menuCheck = false; public bool MenuCheck { set { _menuCheck = value; } } protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs e) { // マウスダウンフラグOn this._onMouseDown = true; base.OnMouseDown(e); } protected override void OnItemSelectionChanged(System.Windows.Forms.ListViewItemSelectionChangedEventArgs e) { if (true == this._onMouseDown) { // チェック状態変更禁止フラグOn this._checkEnable = false; } base.OnItemSelectionChanged(e); } protected override void OnItemCheck(System.Windows.Forms.ItemCheckEventArgs ice) { if (!_menuCheck && (false == this._checkEnable || (this._checkEnable && this.SelectedItems.Count > 1))) { // チェック状態変更イベントキャンセル iceice.NewValue = ice.CurrentValue; return; } base.OnItemCheck(ice); } protected override void OnMouseUp(System.Windows.Forms.MouseEventArgs e) { // フラグOff this._checkEnable = true; this._onMouseDown = false; base.OnMouseUp(e); } } }