리스트 뷰 컨트롤이 모든 클릭을 컨트롤 키를 통해 처리 한 것처럼 처리하도록하는 방법이 있습니까?리스트 뷰 다중 선택
사용자가 여러 항목을 동시에 선택할 수 있도록하기 위해 컨트롤 키 (항목 선택 및 선택 상태 해제) 기능을 복제해야합니다.
미리 감사드립니다.
리스트 뷰 컨트롤이 모든 클릭을 컨트롤 키를 통해 처리 한 것처럼 처리하도록하는 방법이 있습니까?리스트 뷰 다중 선택
사용자가 여러 항목을 동시에 선택할 수 있도록하기 위해 컨트롤 키 (항목 선택 및 선택 상태 해제) 기능을 복제해야합니다.
미리 감사드립니다.
MultiSelect가 true로 설정된 경우에도 ListView 컨트롤의 표준 동작은 아닙니다. 당신이 당신의 자신의 사용자 지정 컨트롤을 만들고 싶었 경우
다음을 수행해야합니다 :
컨트롤 키를 사용하지 않고도 다중 선택이 가능하고 구현하기에 충분히 간단해야합니다!
Ctrl + 클릭 동작은 브라우저에서 구현 한 동작이며 실제 .NET 컨트롤과는 거의 관계가 없습니다. 달성하고자하는 결과는 많은 추가 JavaScript로 얻을 수 있습니다. 가장 쉬운 방법은 목록보기를 해킹하려고 시도하는 대신이 방법으로 작동하는 기본 JavaScript 컨트롤을 작성하는 것입니다. 이것이 바람직한 것이겠습니까? 이 경우 나는 그것을 들여다보고 해결책을 가지고 다시 당신에게 돌아갈 수 있습니다.
그는 브라우저와 관련이 없으며 C#과 WinForms를 사용하고 있습니다! –
어쨌든 Javascript는 winforms 환경에서 사용할 수 없습니다. – Evan
ListviewItemCollection을 드릴 다운하여 개별 항목의 Selected 속성을 true로 설정할 수 있습니다. 이것은 내가 재현하려는 "다중 선택"기능을 모방 한 것입니다. (위의 주석자가 언급했듯이, lisetview의 MultiSelect 속성을 true로 설정해야합니다.)
목록보기에서 Checkboxes을 사용하는 것도 좋습니다. Ctrl + 클릭에 대해 알지 못할 수도있는 일반 사용자에게 다중 선택 개념을 전달하는 것은 분명한 방법입니다. 은 MSDN 페이지에서
:체크 박스 속성은 Ctrl 키를 사용하지 않고 ListView 컨트롤에서 여러 항목을 선택하는 방법을 제공합니다. 응용 프로그램에 따라 표준 다중 선택 방법 대신 항목을 선택하기 위해 확인란을 사용하면 사용자가 더 쉽게 수행 할 수 있습니다. ListView 컨트롤의 MultiSelect 속성이 false로 설정된 경우에도 확인란을 표시하고 여러 선택 기능을 사용자에게 제공 할 수 있습니다. 이 기능은 여러 항목을 선택하지 않고 사용자가 응용 프로그램 내에서 작업을 수행하기 위해 목록에서 여러 항목을 선택할 수 있도록하려는 경우 유용 할 수 있습니다.
여기 WndProc을 사용하여이 문제를 해결하는 데 사용한 완전한 해결책이 있습니다. 기본적으로 마우스를 클릭하면 히트 테스트가 수행됩니다. MutliSelect가 켜져 있으면 항목이 자동으로 켜기/끄기 [.Selected]로 전환되며 다른 목록을 유지하거나 ListView 기능을 사용하는 것을 걱정하지 않아도됩니다.
모든 시나리오에서 이것을 테스트하지는 않았지만, 저에게 효과적이었습니다. YMMV.
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();
}
}
다른 사람이이 기사를 검색하여 발견 한 경우, 허용 된 솔루션은 더 이상 유효하지 않습니다. (실제로 나는 그것이 이제까지 있었다라고 확신하지 않는다). 원하는 것을 수행하려면 (수정 자 키없이 다중 선택) 간단히 목록보기 선택 유형을 확장하지 않고 다중으로 설정하십시오. 다중은 클릭 할 때마다 하나의 항목을 선택하고, 확장 키를 먼저 눌러야합니다.
이 질문에 대한 답을 제공하지 않습니다. 충분한 [평판] (http://stackoverflow.com/help/whats-reputation)이 있으면 [모든 게시물에 댓글을 달 수 있습니다] (http://stackoverflow.com/help/privileges/comment); 대신에 [질문자의 설명이 필요없는 답변을 제공하십시오] (http://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can- i-do- 대신). - [검토 중] (검토 중/리뷰/저품목/13911675) –
질문에 대한 답변을 제공하지 않는 방법을 잘 모릅니다. 질문은 "목록보기 컨트롤이 모든 클릭을 Ctrl 키를 통해 처리 된 것처럼 취급하도록 할 수있는 방법이 있습니까?" 내가 준 응답은 "다중 선택 속성을 확장되지 않은 다중 값으로 설정"했습니다. 원래의 질문에 대한 정확하고 올바른 답변입니다. 오, 그게 내가 맹세코 오래된 해결책을 통해 다른 사람들을 도우려는 마지막 시도입니다. – kamikazi
나는이 선을 따라 일해 왔지만 문제가 더 쉬운지 확인하고보고자 함으로서 문제를 해결하기를 원했습니다. 답변을 주셔서 감사합니다. – Evan
선택한 항목의 목록에 색인이 아닌 "내용"이 저장되어 있는지 확인하십시오. 이 인덱스를 사용하는 것이 더 쉬울지라도 ListBox.ItemsCollection과 목록을 동기화 된 상태로 유지해야한다는 의미입니다. 다행히도 당신의 객체 또는 문자열은이 관계를 유지할만큼 충분히 독특합니다! –