有什麼辦法強制listview控件將所有的點擊視爲通過Control鍵完成嗎?Listview Multiple Selection
我需要複製使用控制鍵(選擇項目設置和取消其選擇狀態)的功能,以便用戶可以輕鬆地同時選擇多個項目。
預先感謝您。
有什麼辦法強制listview控件將所有的點擊視爲通過Control鍵完成嗎?Listview Multiple Selection
我需要複製使用控制鍵(選擇項目設置和取消其選擇狀態)的功能,以便用戶可以輕鬆地同時選擇多個項目。
預先感謝您。
即使將MultiSelect設置爲true,它也不是ListView控件的標準行爲。
如果你想創建自己的自定義控制,你需要做到以下幾點:
應該是很簡單的實現,感覺像多選不使用控制鍵!
Ctrl + Click行爲與瀏覽器一樣,並且與實際的.NET控件無關。您試圖實現的結果可以通過很多額外的JavaScript來獲得 - 最簡單的方法可能是從默認情況下構建一個JavaScript控件,而不是試圖破解列表視圖。這會是可取的嗎?在這種情況下,我可以研究它並通過解決方案回覆給您。
與瀏覽器無關,他使用C#和WinForms! – 2008-09-17 14:57:32
無論如何,Javascript不能用於winforms環境。 – Evan 2008-09-17 14:58:42
向下鑽取ListviewItemCollection,您可以將單個項目的Selected屬性設置爲true。我相信,這將模擬您嘗試複製的「多選」功能。 (另外,正如上面提到的評論者一樣,一定要將lisetview的MultiSelect屬性設置爲true。)
您可能還想在列表視圖上使用Checkboxes。這是將多選概念傳達給不瞭解Ctrl + Click的普通用戶的一種顯而易見的方式。
從MSDN頁:
複選框屬性提供了一種方法來選擇ListView控件的多個項目,而無需使用CTRL鍵。根據您的應用程序,使用複選框選擇項目而不是標準多選方法可能會更容易爲用戶。即使ListView控件的MultiSelect屬性設置爲false,仍然可以顯示覆選框並向用戶提供多種選擇功能。如果您不想要選擇多個項目,但仍希望允許用戶從列表中選擇多個項目以在應用程序中執行操作,則此功能可能很有用。
這裏是我用WndProc解決這個問題的完整解決方案。基本上,當點擊鼠標時它會進行點擊測試..然後如果打開MutliSelect,它會自動切換項目開/關[.Selected],而不用擔心維護任何其他列表或混淆ListView功能。
我還沒有在所有場景中測試過這個...它對我有用。因人而異。
public class MultiSelectNoCTRLKeyListView : ListView {
public MultiSelectNoCTRLKeyListView() {
}
public const int WM_LBUTTONDOWN = 0x0201;
protected override void WndProc(ref Message m) {
switch (m.Msg) {
case WM_LBUTTONDOWN:
if (!this.MultiSelect)
break;
int x = (m.LParam.ToInt32() & 0xffff);
int y = (m.LParam.ToInt32() >> 16) & 0xffff;
var hitTest = this.HitTest(x, y);
if (hitTest != null && hitTest.Item != null)
hitTest.Item.Selected = !hitTest.Item.Selected;
return;
}
base.WndProc(ref m);
}
}
這是一個完整的解決方案,它是由上面的Matthew M.提供的解決方案的修改。
它提供了一個改進以及一些附加功能。
改進: - 左鍵單擊控件將焦點放在控件上。 - 點擊鼠標右鍵的行爲是一致的(單選)
新增功能: - 控制有一個屬性(MultiSelectionLimit),它允許你把多少項目可以一次選擇的限制。
我第一次發佈後,我意識到代碼的一個小問題。清除多個選擇會導致多次調用ItemSelectionChanged事件。我無法避免使用當前的繼承來避免這種情況,相反,我採用了一種解決方案,其中bool屬性SelectionsBeingCleared將爲true,直到取消選擇所有選定的項目。通過這種方式,對該屬性的簡單調用將可以避免更新效果,直到所有多個選擇都被清除。
public class ListViewMultiSelect : ListView
{
public const int WM_LBUTTONDOWN = 0x0201;
public const int WM_RBUTTONDOWN = 0x0204;
private bool _selectionsBeingCleared;
/// <summary>
/// Returns a boolean indicating if multiple items are being deselected.
/// </summary>
/// <remarks> This value can be used to avoid updating through events before all deselections have been carried out.</remarks>
public bool SelectionsBeingCleared
{
get
{
return this._selectionsBeingCleared;
}
private set
{
this._selectionsBeingCleared = value;
}
}
private int _multiSelectionLimit;
/// <summary>
/// The limit to how many items that can be selected simultaneously. Set value to zero for unlimited selections.
/// </summary>
public int MultiSelectionLimit
{
get
{
return this._multiSelectionLimit;
}
set
{
this._multiSelectionLimit = Math.Max(value, 0);
}
}
public ListViewMultiSelect()
{
this.ItemSelectionChanged += this.multiSelectionListView_ItemSelectionChanged;
}
public ListViewMultiSelect(int selectionsLimit)
: this()
{
this.MultiSelectionLimit = selectionsLimit;
}
private void multiSelectionListView_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
{
if (e.IsSelected)
{
if (this.MultiSelectionLimit > 0 && this.SelectedItems.Count > this.MultiSelectionLimit)
{
this._selectionsBeingCleared = true;
List<ListViewItem> itemsToDeselect = this.SelectedItems.Cast<ListViewItem>().Except(new ListViewItem[] { e.Item }).ToList();
foreach (ListViewItem item in itemsToDeselect.Skip(1)) { item.Selected = false; }
this._selectionsBeingCleared = false;
itemsToDeselect[0].Selected = false;
}
}
}
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_LBUTTONDOWN:
if (this.SelectedItems.Count == 0 || !this.MultiSelect) { break; }
if (this.MultiSelectionLimit > 0 && this.SelectedItems.Count > this.MultiSelectionLimit) { this.ClearSelections(); }
int x = (m.LParam.ToInt32() & 0xffff);
int y = (m.LParam.ToInt32() >> 16) & 0xffff;
ListViewHitTestInfo hitTest = this.HitTest(x, y);
if (hitTest != null && hitTest.Item != null) { hitTest.Item.Selected = !hitTest.Item.Selected; }
this.Focus();
return;
case WM_RBUTTONDOWN:
if (this.SelectedItems.Count > 0) { this.ClearSelections(); }
break;
}
base.WndProc(ref m);
}
private void ClearSelections()
{
this._selectionsBeingCleared = true;
SelectedListViewItemCollection itemsToDeselect = this.SelectedItems;
foreach (ListViewItem item in itemsToDeselect.Cast<ListViewItem>().Skip(1)) { item.Selected = false; }
this._selectionsBeingCleared = false;
this.SelectedItems.Clear();
}
}
爲防萬一其他人搜索並找到本文,接受的解決方案不再有效。 (實際上我不確定它曾經是)。爲了做你想做的事(選擇不帶修飾鍵的倍數)只需將列表視圖選擇類型設置爲多個,而不是擴展。點擊時,多個選擇一個接一個項目,並且擴展需要首先按下修飾鍵。
我自己一直在沿着這些方向努力,但我想在檢查修復之前檢查並確定是否有更簡單的方法。 儘管感謝您的回答。 – Evan 2008-09-17 15:01:23