ListBox.SelectionMode =“None”이 없습니다. 목록 상자에서 선택을 비활성화하는 다른 방법이 있습니까?


189

ListBox에서 선택을 비활성화하려면 어떻게합니까?


1
선택할 수없는 ListBox를 갖는 것이 유효한 예제를 제공 할 수 있습니까? 주요 동작은 항목을 선택하는 것입니다. 아마를 표시하는 또 다른 방법을 선택 것이다 (이 날은 비평가가 아니라이 발생할 수있는 경우에 진정한 관심려고 노력하지 않음).
Marthin

3
@Martin : 예를 들어 목록 상자 항목에서 컨텐츠를 드래그하려는 경우이 항목을 선택하는 데 관심이 없을 것입니다. 또한 : 항목을 드래그 할 때 : 목록 상자 내에서 드래그하는 동안 선택한 목록 상자의 항목 변경-이 게시물을 참조하십시오 stackoverflow.com/questions/7589142/…
Danield

1
Shimmy가 ListBox를 사용하고 싶은 이유는 asker가 목록 상자를 언젠가 선택할 수있게 만들었 기 때문이라고 생각합니다. 그 질문은 나에게도 가치가있다. 카드 게임을하고 있다고 가정 해 봅시다. 당신은 당신의 카드에서 하나의 카드를 선택할 수 있습니다, 때로는, 당신은 여러 개를 선택할 수 있으며, 다른 경우에는 선택할 수 없습니다.
Gqqnbig

1
또한 때로는 10 장의 카드가 있으며 그 중 4 장만 선택할 수 있습니다. 4 개 중에서 3 개까지 선택할 수 있습니다.
Gqqnbig

1
@Marthin : ListBox에 GridView가있을 때. Gridview 헤더는 다른 곳에서는 사용할 수없는 많은 기능을 제공합니다. 그리고 그리드 뷰의 셀에 편집 컨트롤이 있습니다.
로빈 데이비스

답변:


264

접근법 1- ItemsControl

의 다른 측면이 필요하지 않으면 대신 ListBox사용할 수 있습니다 ItemsControl. 항목을 배치 ItemsPanel하고 선택 개념이 없습니다.

<ItemsControl ItemsSource="{Binding MyItems}" />

기본적 ItemsControl으로 하위 요소의 가상화는 지원하지 않습니다. 항목이 많은 경우 가상화는 메모리 사용량을 줄이고 성능을 향상시킬 수 있습니다.이 경우 접근 방식 2를 사용하고 스타일을 지정 ListBox하거나 에 가상화를 추가 할 수 있습니다ItemsControl .

접근법 2-스타일링 ListBox

또는 선택 영역이 보이지 않도록 ListBox의 스타일을 지정하십시오.

<ListBox.Resources>
  <Style TargetType="ListBoxItem">
    <Style.Resources>
      <!-- SelectedItem with focus -->
      <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
                       Color="Transparent" />
      <!-- SelectedItem without focus -->
      <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}"
                       Color="Transparent" />
      <!-- SelectedItem text foreground -->
      <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}"
                       Color="Black" />
    </Style.Resources>
    <Setter Property="FocusVisualStyle" Value="{x:Null}" />
  </Style>
</ListBox.Resources>

24
아니요, 실제 선택 동작이 아닌 시각 효과 만 변경됩니다.
Thomas Levesque

8
나의 첫번째 제안은 ItemsControl을 사용하는 것이었다. 당신이 그리워? :)
Drew Noakes

5
이 의견을 다시 읽으면 @Thomas Levesque의 의견이 내가 보여주는 두 번째 접근 방식에만 해당된다는 것을 지적하고 싶습니다. 일반 ItemsControl을 사용하면 선택 개념이 완전히 제거됩니다.
Drew Noakes

1
ItemsControl 솔루션은 상자 스크롤 지원 (스크롤바 및 마우스 휠)을 제거합니다.
MuiBienCarlota

1
접근법 1-ItemsControl의 경우 +1 스크롤해야하는 거대한 페이지가있는 경우 사용자가 ListBox 위로 마우스를 가져 가면 목록 상자에서 MouseWheel 이벤트를 가져 와서 MouseWheel이 효과적으로 비활성화됩니다. 즉, 마우스가 목록 상자 위에 있는지 여부에 따라 전체 페이지를 스크롤하는 데 사용되는 마우스 휠의 작동이 임의로 중단된다는 사용자의 불만이 있습니다.
Contango

159

나는 나를 위해 일하는 매우 간단하고 직접적인 해결책을 찾았습니다.

<ListBox ItemsSource="{Items}">
    <ListBox.ItemContainerStyle>
       <Style TargetType="{x:Type ListBoxItem}">
           <Setter Property="Focusable" Value="False"/>
       </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

나는 그가 여기에서 아주 잘했다고 생각합니다 : asaddurrani.wordpress.com/tag/wpf-listbox-disable-selection
Sid

3
이것은 완벽 해요. 선택한 항목과 버튼과 같은 다른 컨트롤이 여전히 작동하지 못하게합니다. 내가 찾던 정확히
Franck

1
이 접근법의 경우 +1 스크롤해야하는 거대한 페이지가있는 경우 사용자가 ListBox 위로 마우스를 가져 가면 목록 상자에서 MouseWheel 이벤트를 가져 와서 MouseWheel이 효과적으로 비활성화됩니다. 즉, 마우스가 목록 상자 위에 있는지 여부에 따라 전체 페이지를 스크롤하는 데 사용되는 마우스 휠의 작동이 임의로 중단된다는 사용자의 불만이 있습니다.
Contango

우수한. 항목을 선택하지 않고 항목의 다른 영역을 클릭 한 경우에만 항목에 버튼이 필요할 때도 비슷한 접근 방식이 효과적이었습니다. 간단히 버튼을 설정하십시오 Focusable = "False"!
Jony Adamit 2016 년

1
이 추가 특성을 추가하여 마우스 오버 강조 표시도 제거하십시오. <Setter Property="IsHitTestVisible" Value="False" />
DonBoitnott

25

ItemsControl대신 을 사용하도록 전환 할 수 있습니다 ListBox. 는 ItemsControl선택의 개념이 없기 때문에 해제 아무것도 없다.


2
매력적인. 나는 당신이 ItemsControl을 직접 선언 할 수 있다는 것을 결코 몰랐다. 나는 그것이 가상 (MustOverride)이라고 생각했다.
Shimmy Weitzhandler

그러나 ItemsControl은 여전히 ​​내 항목을 한 줄로 렌더링합니까?
크라이

@Chry 예, 추가로 언제든지 수동으로을 설정할 수 있습니다 ItemTemplate.
Shimmy Weitzhandler

2
이로 인해 스크롤과 같은 너무 많은 기능이 손실됩니다.
Jeff

@Jeff 당신은 ScrollControler에서 ItemsControl을 감싸서 스크롤 할 수 있습니다.
Wilka

12

고려해야 할 또 다른 옵션은 ListBoxItems를 비활성화하는 것입니다. 다음 스 니펫에 표시된대로 ItemContainerStyle을 설정하면됩니다.

<ListBox ItemsSource="{Binding YourCollection}">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="IsEnabled" Value="False" />
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

텍스트를 회색으로 표시하지 않으려면 {x : Static SystemColors.GrayTextBrushKey} 키를 사용하여 스타일의 리소스에 브러시를 추가하여 비활성화 된 색상을 지정할 수 있습니다. 다른 솔루션은 ListBoxItem 컨트롤 템플릿을 재정의하는 것입니다.


간단하고 작동합니다. 감사합니다! 그리고 WP 8.1 Runtime에도 적용됩니다.
Malutek

8

itemscontrol 대신 listbox를 사용해야하는 경우에도 작동하지만 선택할 수 없어야하는 항목 만 표시하고 있습니다.

<ListBox.ItemContainerStyle>
    <Style TargetType="ListBoxItem">
        <Setter Property="IsHitTestVisible" Value="False" />
    </Style>
</ListBox.ItemContainerStyle>

3

여기에 꽤 좋은 답변이 있지만 약간 다른 것을 찾고있었습니다. 선택을 원하지만 선택하거나 다른 문제로 표시하고 싶지 않습니다.

위의 솔루션은 (완전히) 작동하지 않았으므로 다른 작업을 수행했습니다. 목록 상자에 새로운 스타일을 사용하여 템플릿을 완전히 재정의했습니다.

<Style x:Key="PlainListBoxStyle" TargetType="ListBox">
    <Setter Property="ItemContainerStyle">
        <Setter.Value>
            <Style TargetType="ListBoxItem">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ListBoxItem">
                            <ContentPresenter />
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListBox}">
                <ItemsPresenter/>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

그것부터 시작하여 자신만의 선택 강조 표시를 쉽게 추가하거나 전혀 원하지 않는 경우 그대로 두십시오.


2

@Drew Noakes의 답변은 대부분의 경우 빠른 솔루션이지만 x : Static 브러쉬 설정과 관련하여 약간의 결함이 있습니다.

제안 된대로 x : Static 브러쉬를 설정하면 목록 상자 항목 내의 모든 자식 컨트롤이이 스타일을 상속합니다.

이는 목록 상자 항목의 강조 표시를 비활성화하는 데 효과적이지만 하위 컨트롤에 원하지 않는 결과를 초래할 수 있음을 의미합니다.

예를 들어, ListBoxItem 내에 ComboBox가 있으면 ComboBox 내에서 마우스 커서를 강조 표시하지 않습니다.

대신,이 스택 오버 플로우 스레드에서 언급 한 솔루션에서 다루는대로 Selected, Unselected 및 MouseOver 이벤트의 VisualStates 설정을 고려 하십시오 . ListBoxItem에서 Control Highlight 제거 (하위 컨트롤 제외) .

프리니


2

또 다른 해결책을 제안합니다. 간단하게 다시 템플릿은 ListBoxItem더 이상 아무것도하기 ContentPresenter때문에 같은 ...

<Style TargetType="{x:Type ListBoxItem}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                <ContentPresenter />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

이 접근법에 대한 나의 이유는 다음과 같습니다.

  1. 제 경우에는 내용과의 사용자 상호 작용을 비활성화하고 싶지 ListBoxItems않으므로 설정할 솔루션이 IsEnabled작동하지 않습니다.

  2. ListBoxItem색상 관련 속성을 재정 의하여 스타일을 다시 시도하는 다른 솔루션 은 템플릿이 해당 속성을 사용하는 인스턴스에서만 작동합니다. 기본 스타일에는 문제가 없지만 사용자 정의 스타일에는 영향을줍니다.

  3. 표준 과 완전히 다른 모양 을 가지고 가상화를 지원하지 않기 ItemsControl때문에 너무 많은 다른 것들을 사용하는 솔루션 은 어쨌든 다시 템플릿해야 합니다.ItemsControlListBoxItemsPanel

위의 기본 모양은 변경 ListBox되지 않으며의 데이터 템플릿에서 항목을 비활성화하지 않으며 ListBox기본적으로 가상화를 지원하며 앱에서 사용 중이거나 사용하지 않을 수있는 스타일에 관계없이 작동합니다. 이것이 KISS 원칙입니다.


1

참고 :이 솔루션은 키보드 탐색 또는 마우스 오른쪽 버튼 클릭 (예 : 화살표 키 다음에 스페이스 키)으로 선택을 비활성화하지 않습니다 .

이전의 모든 답변은 선택 기능을 완전히 제거하거나 (런타임 전환 없음) 시각적 효과를 제거하지만 선택은 제거하지 않습니다.

그러나 사용자 입력이 아닌 코드로 선택을 선택하고 표시하려면 어떻게해야합니까? 전체 Listbox를 비활성화하지 않고 사용자 선택을 "고정"하고 싶습니까?

해결책은 전체 ItemsContentTemplate을 시각적 크롬이없는 Button으로 감싸는 것입니다. 버튼의 크기는 항목의 크기와 같아야하므로 완전히 덮습니다. 이제 버튼의 IsEnabled-Property를 사용하십시오.

항목의 선택 상태를 "고정"하려면 단추를 활성화하십시오. 활성화 된 버튼이 모든 마우스 이벤트를 ListboxItem-Eventhandler로 버블 링하기 전에 먹기 때문에 작동합니다. ItemsDataTemplate은 단추 내용의 일부이기 때문에 여전히 MouseEvents를 수신합니다.

클릭하여 선택 항목을 변경하려면 단추를 비활성화하십시오.

<Style x:Key="LedCT" TargetType="{x:Type ListBoxItem}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                <Button IsEnabled="{Binding IsSelectable, Converter={StaticResource BoolOppositeConverter}}" Template="{DynamicResource InvisibleButton}">
                        <ContentPresenter />
                </Button>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<ControlTemplate x:Key="InvisibleButton" TargetType="{x:Type Button}">
    <ContentPresenter/>
</ControlTemplate>

다 트랙스


1

ItemsControl의 모든 기능이 필요할 수 있습니까? 선택을 허용하지 않습니다 :

<ItemsControl ItemsSource="{Binding Prop1}" ItemTemplate="{StaticResource DataItemsTemplate}" />

3
@ Shimmy : 사소한 답변이 비슷합니다. 어떤 깃발에도 합당한 중복은 없습니다. 이에 대해 더 궁금한 점이 있으면 Meta Stack Overflow 에 문의하십시오 .

0

텍스트 상자를 목록 상자 위에 놓으면 응용 프로그램의 모양이 변경되지 않으며 항목을 선택할 수 없습니다.


1
그래도 탭 탐색을 비활성화해야합니다.
Amanduh

0

예를 들어 Windows Phone에서 작동하는 간단한 수정은 선택된 항목을 null로 선택 설정하는 것입니다.

    <ListBox SelectionChanged="ListBox_SelectionChanged">

그리고 코드 뒤에 :

    private void ListBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
    {
        (sender as ListBox).SelectedItem = null;
    }

0

나는 완벽한 길을 찾았다.
사용자가 마우스를 가리 키거나 아래로 스크롤하거나 위로 스크롤 할 수 없도록 ListBox IsHitTestVisible을 false로 설정하십시오.
Capture PreviewGotKeyboardFocus e.Handled = true이므로 키보드 탭, 위쪽 화살표, 아래쪽 화살표로 항목을 선택할 수 있습니다.

이 방법의 장점 :

  1. 전경의 목록 상자 항목은 회색이되지 않습니다.
  2. ListBox 배경을 투명으로 설정할 수 있습니다

xmal

<ListBox Name="StudentsListBox" ItemsSource="{Binding Students}" ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.HorizontalScrollBarVisibility="Disabled" BorderThickness="0" Background="Transparent" IsHitTestVisible="False" PreviewGotKeyboardFocus="StudentsListBox_PreviewGotKeyboardFocus">

    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="Padding" Value="0"/>
            <Setter Property="Margin" Value="0"/>

            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <Border x:Name="Bd">
                            <ContentPresenter/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="Selector.IsSelectionActive" Value="False" />
                                    <Condition Property="IsSelected" Value="True" />
                                </MultiTrigger.Conditions>
                                <Setter TargetName="Bd" Property="Background" Value="Yellow" />
                                <Setter TargetName="Bd" Property="BorderBrush" Value="Transparent" />
                            </MultiTrigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>

    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid Margin="0,0,0,0">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <TextBlock Grid.Column="0" Name="GradeBlock" Text="{Binding Grade}" FontSize="12" Margin="0,0,5,0"/>
                <TextBlock Grid.Column="1" Name="NameTextBlock" Text="{Binding Name}" FontSize="12" TextWrapping="Wrap"/>
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>

</ListBox>

암호

private void StudentsListBox_PreviewGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
    e.Handled = true;
}

-1

나에게 가장 좋은 해결책은 다음과 같습니다.

        <ListBox.ItemContainerStyle>
            <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="Focusable" Value="True"/>
                <Setter Property="IsHitTestVisible" Value="False" />
            </Style>
        </ListBox.ItemContainerStyle>

-3

IsEnabled = 거짓


2
이것이 내가 찾던 것이 아니라, 모든 회색한다
흔들 Weitzhandler

1
그러나 그것은 간단한 질문에 대한 직접적인 대답입니다 :)
Viktor Jevdokimov

1
직선 앞으로 대답은 이것이다 stackoverflow.com/questions/1398559/1398650#1398650 하지만, 어쨌든 감사합니다
흔들 Weitzhandler

나를 위해 매우 도움이, 나는 회색과 장애인을 원했다!
Martin Robins

-3

목록 상자 / 드롭 다운에서 하나 이상의 옵션을 비활성화하려면 아래와 같이 "disabled"속성을 추가하면됩니다. 이렇게하면 사용자가이 옵션을 선택할 수 없으며 회색 오버레이가 나타납니다.

ListItem item = new ListItem(yourvalue, yourkey);
item.Attributes.Add("disabled","disabled");
lb1.Items.Add(item);

그 당시에는 ASP.NET 솔루션으로 WPF 질문에 대한 답을 얻었습니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.