WPF ListView 선택 해제


119

간단한 WPF ListView와 간단한 질문이 있습니다.

선택을 해제 할 수 있으므로 사용자가 행을 클릭 할 때 행이 강조 표시되지 않습니까?

목록보기

클릭했을 때 행 1이 행 0처럼 보이기를 바랍니다.

관련이있을 수 있음 : 마우스 오버 / 선택의 모양을 지정할 수 있습니까? 예 : 파란색 그라디언트 호버 모양 (3 행)을 사용자 정의 단색으로 대체합니다. 내가 발견 한 불행히도 도움이되지.

(ListView를 사용하지 않고도 동일한 결과를 얻을 수 있습니다. ListView와 마찬가지로 논리적 스크롤링 및 UI 가상화를 사용할 수 있기를 바랍니다.)

ListView의 XAML은 다음과 같습니다.

<ListView Height="280" Name="listView">
    <ListView.Resources>
        <!-- attempt to override selection color -->
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightColorKey}"
                         Color="Green" />
    </ListView.Resources>
    <ListView.View>
        <GridView>
            <GridView.Columns>
                <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" />
                <!-- more columns -->
            </GridView.Columns>
        </GridView>
     </ListView.View>
</ListView>

이전에는 WPF에서 ListView를 사용한 적이 없지만 false로 설정하면 전체 컨트롤을 비활성화하고 원하는 것을 얻을 수있는 일종의 IsEnabled 속성이 있다고 확신합니다. 100 % 확실하지 않습니다.
James McConnell

안녕하세요, 전체 ListView를 비활성화 할 수있는 IsEnabled 속성이 있습니다. 그래도 ListView가 정상적으로 작동하려면 선택 항목을 표시하지 마십시오.
Martin Konicek

답변:


135

가장 간단한 방법으로 항목 선택을 완전히 비활성화하려면 Martin Konicek의 의견에 따라 :

<ListView>
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="Focusable" Value="false"/>
        </Style>
    </ListView.ItemContainerStyle>
    ...
</ListView>

그러나 항목을 선택할 수있는 것과 같이 ListView의 기능이 여전히 필요한 경우 다음과 같이 선택한 항목의 스타일을 시각적으로 비활성화 할 수 있습니다.

ListViewItem의 ControlTemplate 을 변경하는 것부터 스타일을 설정하는 것 까지 다양한 방법으로이 작업을 수행 할 수 있습니다 (훨씬 쉬움). ItemContainerStyle을 사용하여 ListViewItems에 대한 스타일을 만들고 선택한 경우 배경 및 테두리 브러시를 '끄기'할 수 있습니다.

<ListView>
    <ListView.ItemContainerStyle>
        <Style TargetType="{x:Type ListViewItem}">
            <Style.Triggers>
                <Trigger Property="IsSelected"
                         Value="True">
                    <Setter Property="Background"
                            Value="{x:Null}" />
                    <Setter Property="BorderBrush"
                            Value="{x:Null}" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </ListView.ItemContainerStyle>
    ...
</ListView>

또한 항목이 선택 될 때 (또는 테스트 용으로 만) 사용자에게 알리는 다른 방법이없는 경우 값을 나타내는 열을 추가 할 수 있습니다.

<GridViewColumn Header="IsSelected"
                DisplayMemberBinding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListViewItem}}, Path=IsSelected}" />

2
관련 부분을 보지 못했지만 IsMouseOver 속성에서 원하는대로 배경과 테두리를 설정하여 동일한 작업을 수행 할 수 있습니다.
rmoore 2009-06-26

88
이제 더 잘 해결했습니다. <Setter Property = "Focusable"Value = "false"/>는 행 선택을 완전히 비활성화합니다.
Martin Konicek

8
아, 시각적으로 선택 기능을 끄려는 거라고 생각했습니다. 항목을 전혀 선택하지 않으려면 ItemsControl을 사용하여 살펴볼 수 있습니다 (포커스 할 수없는 경우 코드를 통해 선택한 항목을 설정할 수 있기 때문에). 다음과 같이해야합니다 : manicprogrammer.com/cs/blogs/… 또한 아직 읽지 않았다면 WPF 및 XAML에 대한 훌륭한 소개를 제공하는 WPF Unleashed 책을 확인하는 것이 좋습니다.
rmoore 2009-06-26

2
@MartinKonicek 나는 그것이 오래된 게시물이라는 것을 알고 있지만 높은 평가를받은 댓글은 답변이어야합니다;)
WiiMaxx

1
@MartinKonicek 나는 추가했다 BasedOn="{StaticResource {x:Type ListViewItem}}"내 그리드 스타일의 나머지 부분을 무시하지 않았다, 그래서, 그러나 나는 또한 당신이 당신의 코멘트 허용 대답해야한다 생각
JumpingJezza

31

Moore의 대답은 작동하지 않으며 여기 페이지 :

ListBox의 항목에 대한 선택 색상, 내용 정렬 및 배경색 지정

작동하지 않는 이유를 설명합니다.

목록보기에 기본 텍스트 만 포함 된 경우 문제를 해결하는 가장 간단한 방법은 투명한 브러시를 사용하는 것입니다.

<Window.Resources>
  <Style TargetType="{x:Type ListViewItem}">
    <Style.Resources>
      <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="#00000000"/>
      <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="#00000000"/>
    </Style.Resources>
  </Style>
</Window.Resources>

목록보기의 셀이 콤보 상자와 같은 컨트롤을 보유하고 있으면 색상도 변경되므로 원하지 않는 결과가 생성됩니다. 이 문제를 해결하려면 컨트롤의 템플릿을 다시 정의해야합니다.

  <Window.Resources>
    <Style TargetType="{x:Type ListViewItem}">
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="{x:Type ListViewItem}">
            <Border SnapsToDevicePixels="True" 
                    x:Name="Bd" 
                    Background="{TemplateBinding Background}" 
                    BorderBrush="{TemplateBinding BorderBrush}" 
                    BorderThickness="{TemplateBinding BorderThickness}" 
                    Padding="{TemplateBinding Padding}">
              <GridViewRowPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
                                    VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
                                    Columns="{TemplateBinding GridView.ColumnCollection}" 
                                    Content="{TemplateBinding Content}"/>
            </Border>
            <ControlTemplate.Triggers>
              <Trigger Property="IsEnabled" 
                       Value="False">
                <Setter Property="Foreground" 
                        Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
              </Trigger>
            </ControlTemplate.Triggers>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>
  </Window.Resources>

14
이것은 내 ListView에 내 모든 항목이 사라지게
척 야만인

18

Focusable이 false로 설정되도록 각 ListViewItem의 스타일을 설정합니다.

<ListView ItemsSource="{Binding Test}" >
    <ListView.ItemContainerStyle>
        <Style TargetType="{x:Type ListViewItem}">
            <Setter Property="Focusable" Value="False"/>
        </Style>
    </ListView.ItemContainerStyle>
</ListView>

4
간단하고 효율적입니다. 그리고 실제로 요청 된 작업을 수행합니다. 선택 항목을 숨기는 대신 해제합니다. 이것이 최고의 답변입니다.
Fumidu

13

Blend의 ListViewItem에 대한 기본 템플릿은 다음과 같습니다.

기본 ListViewItem 템플릿 :

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListViewItem}">
                    <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                        <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsSelected" Value="true">
                            <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
                        </Trigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsSelected" Value="true"/>
                                <Condition Property="Selector.IsSelectionActive" Value="false"/>
                            </MultiTrigger.Conditions>
                            <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}}"/>
                        </MultiTrigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>

기본 템플릿을 대체하기 위해 스타일에 아래 코드를 추가하여 IsSelected 트리거 및 IsSelected / IsSelectionActive MultiTrigger를 제거하면 선택시 시각적 변경이 없습니다.

IsSelected 속성의 시각적 변경 사항을 해제하는 솔루션 :

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListViewItem}">
                <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>

12

내가 찾은 가장 쉬운 방법 :

<Setter Property="Focusable" Value="false"/>

4
@Mutex 작동합니다- ListView.ItemContainerStyle그래도 이것을 적용해야합니다 !
Andreas Niedermair

8

위의 솔루션에 추가로 ... MultiTrigger를 사용하여 ListViewItem의 스타일이 다음과 같도록 선택한 후에도 MouseOver 강조 표시가 계속 작동하도록 허용합니다.

        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Style.Triggers>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsSelected" Value="True" />
                            <Condition Property="IsMouseOver" Value="False" />
                        </MultiTrigger.Conditions>
                        <MultiTrigger.Setters>
                            <Setter Property="Background" Value="{x:Null}" />
                            <Setter Property="BorderBrush" Value="{x:Null}" />
                        </MultiTrigger.Setters>
                    </MultiTrigger>
                </Style.Triggers>
            </Style>
        </ListView.ItemContainerStyle>

6

좋아, 게임에 조금 늦었지만 이러한 솔루션 중 어느 것도 내가하려는 일을 제대로 수행하지 못했습니다. 이러한 솔루션에는 몇 가지 문제가 있습니다.

  1. 스타일을 망치고 모든 자식 컨트롤을 비활성화하는 ListViewItem을 비활성화합니다.
  2. 적중 테스트 스택에서 제거합니다. 즉, 자식 컨트롤에 마우스 오버 나 클릭이 발생하지 않습니다.
  3. 초점을 맞출 수 없게 만드세요. 이건 그냥 평범하지 않았나요?

그룹화 헤더가있는 ListView를 원했고 각 ListViewItem은 선택하거나 마우스를 올려 놓지 않고 '정보 용'이어야하지만 ListViewItem에는 클릭 할 수 있고 마우스를 올려 놓고 싶은 버튼이 있습니다.

그래서 제가 원하는 것은 ListViewItem이 전혀 ListViewItem이되지 않도록하는 것입니다. 그래서 저는 ListViewItem의 ControlTemplate을 타서 간단한 ContentControl로 만들었습니다.

<ListView.ItemContainerStyle>
    <Style TargetType="ListViewItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <ContentControl Content="{Binding Content, RelativeSource={RelativeSource TemplatedParent}}"/>
                </ControlTemplate>
            </Setter.Value>
         </Setter>
     </Style>
</ListView.ItemContainerStyle>

5

목록보기의 속성 중 하나는 IsHitTestVisible. 선택을 취소하십시오.


간단하고 효과적이며 ScrollViewer가 목록보기를 감싸서 내 문제를 해결합니다.
Brian Ng

1
listview itemtemplate 안에 버튼 템플릿이 있습니다. 선택을 취소 IsHitTestVisible하면 버튼을 클릭 할 수 없습니다. 그것은처럼 행동IsEnabled = false;
Luiey

1

이는 다음 요구 사항을 충족 할 수있는 다른 사용자를위한 것입니다.

  1. 표준 강조 표시의 색상을 변경하는 것 외에도 "선택됨"의 시각적 표시를 완전히 대체합니다 (예 : 모양 사용).
  2. 이 선택된 표시를 모델의 다른 시각적 표현과 함께 DataTemplate에 포함하지만,
  3. 모델 클래스에 "IsSelectedItem"속성을 추가하고 모든 모델 개체에서 해당 속성을 수동으로 조작해야하는 부담을 원하지 않습니다.
  4. ListView에서 항목을 선택할 수 있어야합니다.
  5. 또한 IsMouseOver의 시각적 표현을 바꾸고 싶습니다.

나처럼 (.NET 4.5와 함께 WPF 사용) 스타일 트리거와 관련된 솔루션이 단순히 작동하지 않는다는 것을 발견했다면 여기에 내 솔루션이 있습니다.

스타일에서 ListViewItem의 ControlTemplate을 바꿉니다.

<ListView ItemsSource="{Binding MyStrings}" ItemTemplate="{StaticResource dtStrings}">
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ListViewItem">
                            <ContentPresenter/>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListView.ItemContainerStyle>
    </ListView>

.. 그리고 DataTemplate :

<DataTemplate x:Key="dtStrings">
        <Border Background="LightCoral" Width="80" Height="24" Margin="1">
            <Grid >
                <Border Grid.ColumnSpan="2" Background="#88FF0000" Visibility="{Binding RelativeSource={RelativeSource AncestorType=ListViewItem}, Path=IsMouseOver, Converter={StaticResource conBoolToVisibilityTrueIsVisibleFalseIsCollapsed}}"/>
                <Rectangle Grid.Column="0" Fill="Lime" Width="10" HorizontalAlignment="Left" Visibility="{Binding RelativeSource={RelativeSource AncestorType=ListViewItem}, Path=IsSelected, Converter={StaticResource conBoolToVisibilityTrueIsVisibleFalseIsCollapsed}}" />
                <TextBlock Grid.Column="1" Text="{Binding}" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" />
            </Grid>
        </Border>
    </DataTemplate>

런타임시 결과 (항목 'B'가 선택되고 항목 'D'가 마우스를 가져옴) :

ListView 모양


1

다음 코드를 사용하십시오.

   <ListView.ItemContainerStyle>
          <Style TargetType="{x:Type ListViewItem}">
           <Setter Property="Background" Value="Transparent`enter code here`" />
             <Setter Property="Template">
               <Setter.Value>
                 <ControlTemplate TargetType="{x:Type ListViewItem}">
                   <ContentPresenter />
                 </ControlTemplate>
               </Setter.Value>
             </Setter>
          </Style>
   </ListView.ItemContainerStyle>

0

아래 코드는 ListViewItem 행 선택을 비활성화하고 패딩, 여백 등을 추가 할 수도 있습니다.

<ListView.ItemContainerStyle>                                                                              
   <Style TargetType="ListViewItem">                                                                                      
       <Setter Property="Template">                                                                                            
         <Setter.Value>                                                                                             
           <ControlTemplate TargetType="{x:Type ListViewItem}">                                                                                                    
              <ListViewItem Padding="0" Margin="0">                                                                                                        
                  <ContentPresenter />
              </ListViewItem>
           </ControlTemplate>                                                          
         </Setter.Value>                                                                                       
         </Setter>
      </Style>                                                                      
  </ListView.ItemContainerStyle> 

0

아래 코드는 ListViewItem에 초점을 사용하지 않도록 설정합니다.

<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
    <Setter Property="Background" Value="Transparent" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListViewItem}">
                <ContentPresenter />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.