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、2009年

回答:


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年

88
私はそれをさらによく解決しました-<Setter Property = "Focusable" Value = "false" />は行の選択を完全に無効にします。
Martin Konicek、2009年

8
ああ、私はあなたが視覚的に選択をオフにすることを意味すると思った。それらをまったく選択したくない場合は、ItemsControlを使用して確認することをお勧めします(フォーカスされていない場合でも、コードを使用して選択した項目を設定できるため)。 「manicprogrammer.com/cs/blogs/…」というようなことをする必要があります。また、まだ読んでいない場合は、WPF Unleashedという本をチェックしてみてください。
rmoore 2009年

2
@MartinKonicek私はそれが古い投稿であることを知っていますが、あなたの高評価コメントは答えになるはずです;)
WiiMaxx

1
@MartinKonicek BasedOn="{StaticResource {x:Type ListViewItem}}"グリッドスタイルの残りの部分を上書きしないように追加する必要がありましたが、コメントを承認済みの回答にする必要があると思います
JumpingJezza

31

ムーアの答えはうまくいきません、そしてここのページ:

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のすべてのアイテムが非表示になります
Chuck Savage

18

各ListViewItemのスタイルを設定して、Focusableをfalseに設定します。

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

4
シンプルで効率的。そして、それは実際に尋ねられたことを行います:それは単にそれを非表示にするのではなく、選択をオフにします。これが最良の答えです。
Fumidu 2015年

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 Triggerと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>


8

上記のソリューションに加えて... MultiTriggerを使用して、選択後にListOverItemのスタイルが次のようになるように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

リストビューのプロパティの1つはIsHitTestVisibleです。オフにします。


シンプルで効果的で、リストビューの外側にScrollViewerをラップして問題を解決します。
Brian Ng 2017

1
listview itemtemplate内にボタンテンプレートを取得しました。選択を解除IsHitTestVisibleすると、ボタンをクリックできなくなります。それは次のように動作しますIsEnabled = false;
Luiey

1

これは、次の要件が発生する可能性のある他のユーザー向けです。

  1. 標準のハイライトの色を変更するだけでなく、「選択した」の視覚的表示を完全に置き換えます(たとえば、ある種の形状を使用します)。
  2. この選択されたインジケーションをモデルの他の視覚的表現とともにDataTemplateに含めますが、
  3. "IsSelectedItem"プロパティをモデルクラスに追加する必要がなく、すべてのモデルオブジェクトでそのプロパティを手動で操作する必要がありません。
  4. リストビューで項目を選択可能にする必要があります
  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.