WPF ListView matikan seleksi

119

Saya memiliki WPF ListView sederhana dan pertanyaan sederhana:

Apakah mungkin untuk mematikan seleksi, jadi ketika pengguna mengklik baris, baris tersebut tidak disorot?

ListView

Saya ingin baris 1 terlihat seperti baris 0 saat diklik.

Mungkin terkait: dapatkah saya mengatur gaya tampilan hover / selection? Misalnya. untuk mengganti tampilan hover gradien biru (baris 3) dengan warna solid kustom. Saya telah menemukan ini dan ini , sayangnya tidak membantu.

(Mencapai hal yang sama tanpa menggunakan ListView juga dapat diterima. Saya hanya ingin dapat menggunakan pengguliran logis dan virtualisasi UI seperti yang dilakukan ListView)

XAML untuk ListView adalah:

<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>
Martin Konicek
sumber
Saya belum pernah menggunakan ListView di WPF sebelumnya, tetapi saya yakin bahwa ada semacam properti IsEnabled yang, jika disetel ke false, akan menonaktifkan seluruh kontrol dan mungkin akan mencapai apa yang Anda cari, tapi saya tidak 100% yakin.
James McConnell
Hai, ya ada properti IsEnabled, yang dapat menonaktifkan seluruh ListView. Saya membutuhkan ListView agar berfungsi normal, hanya saja jangan menampilkan seleksi.
Martin Konicek

Jawaban:

135

Sesuai komentar Martin Konicek, untuk menonaktifkan sepenuhnya pemilihan item dengan cara yang paling sederhana:

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

Namun, jika Anda masih memerlukan fungsionalitas ListView, seperti dapat memilih item, Anda dapat menonaktifkan gaya item yang dipilih secara visual seperti:

Anda dapat melakukan ini dengan berbagai cara, dari mengubah ControlTemplate ListViewItem hingga hanya menyetel gaya (jauh lebih mudah). Anda dapat membuat gaya untuk ListViewItems menggunakan ItemContainerStyle dan 'mematikan' latar belakang dan kuas tepi saat dipilih.

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

Selain itu, kecuali Anda memiliki cara lain untuk memberi tahu pengguna saat item dipilih (atau hanya untuk pengujian), Anda dapat menambahkan kolom untuk mewakili nilai:

<GridViewColumn Header="IsSelected"
                DisplayMemberBinding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListViewItem}}, Path=IsSelected}" />
rmoore
sumber
2
Tidak melihat bagian terkait, tetapi Anda dapat melakukan hal yang sama, mengatur latar belakang dan batas sesuka Anda pada properti IsMouseOver.
lanjut
88
Saya memecahkannya lebih baik sekarang - <Setter Property = "Focusable" Value = "false" /> sepenuhnya menonaktifkan pemilihan baris.
Martin Konicek
8
Ahh, saya pikir maksud Anda matikan saja Seleksi secara visual. Jika Anda tidak ingin mereka dipilih sama sekali, Anda mungkin ingin melihat menggunakan ItemsControl (Karena Anda masih dapat mengatur item yang dipilih melalui kode jika mereka tidak dapat difokuskan), meskipun untuk mendapatkan tampilan Grid Anda Anda harus melakukan sesuatu seperti ini: manicprogrammer.com/cs/blogs/… Selain itu, jika Anda belum melakukannya, Anda mungkin ingin melihat buku WPF Unleashed, karena buku ini memberikan pengantar yang bagus untuk WPF & XAML.
lanjut
2
@MartinKonicek saya tahu itu adalah posting lama tetapi komentar Anda yang dinilai tinggi harus menjadi jawaban;)
WiiMaxx
1
@MartinKonicek Saya harus menambahkan BasedOn="{StaticResource {x:Type ListViewItem}}"sehingga tidak menimpa gaya kisi saya yang lain, tetapi saya juga berpikir Anda harus membuat komentar Anda sebagai jawaban yang diterima
JumpingJezza
31

Jawaban Moore tidak berfungsi, dan halaman di sini:

Menentukan Warna Pilihan, Perataan Konten, dan Warna Latar Belakang untuk item dalam Kotak Daftar

menjelaskan mengapa itu tidak bisa berhasil.

Jika tampilan daftar Anda hanya berisi teks dasar, cara paling sederhana untuk menyelesaikan masalah adalah dengan menggunakan kuas transparan.

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

Ini akan menghasilkan hasil yang tidak diinginkan jika sel listview menahan kontrol seperti kotak kombo, karena itu juga mengubah warnanya. Untuk mengatasi masalah ini, Anda harus menentukan ulang template kontrol.

  <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>
Mark Markindale
sumber
14
Hal ini membuat semua item saya di ListView menghilang
Chuck Savage
18

Setel gaya setiap ListViewItem agar Focusable disetel ke false.

<ListView ItemsSource="{Binding Test}" >
    <ListView.ItemContainerStyle>
        <Style TargetType="{x:Type ListViewItem}">
            <Setter Property="Focusable" Value="False"/>
        </Style>
    </ListView.ItemContainerStyle>
</ListView>
Hayley Guillou
sumber
4
Sederhana dan efisien. Dan itu benar-benar melakukan apa yang diminta: Mematikan pilihan, bukan hanya menyembunyikannya. Inilah jawaban terbaik.
Fumidu
13

Berikut template default untuk ListViewItem dari Blend:

Template ListViewItem Default:

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

Hapus saja IsSelected Trigger dan IsSelected / IsSelectionActive MultiTrigger, dengan menambahkan kode di bawah ini ke Style Anda untuk mengganti template default, dan tidak akan ada perubahan visual saat dipilih.

Solusi untuk mematikan perubahan visual properti 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>
Ben Wilde
sumber
12

Cara termudah yang saya temukan:

<Setter Property="Focusable" Value="false"/>
Martin Konicek
sumber
4
@ Mutex Berhasil - Anda harus menerapkan ini ListView.ItemContainerStyle!
Andreas Niedermair
8

Lebih jauh ke solusi di atas ... Saya akan menggunakan MultiTrigger untuk memungkinkan sorotan MouseOver terus bekerja setelah pemilihan sedemikian rupa sehingga gaya ListViewItem Anda akan menjadi:

        <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>
Anjing merah
sumber
6

Oke, sedikit terlambat ke permainan, tetapi tidak ada solusi ini yang benar-benar melakukan apa yang saya coba lakukan. Solusi ini memiliki beberapa masalah

  1. Nonaktifkan ListViewItem, yang mengencangkan gaya dan menonaktifkan semua kontrol anak
  2. Hapus dari tumpukan hit-test, yaitu kontrol anak tidak pernah mendapatkan mouse-over atau klik
  3. Buat itu tidak bisa difokuskan, ini jelas tidak berhasil untuk saya?

Saya menginginkan ListView dengan tajuk pengelompokan, dan setiap ListViewItem seharusnya hanya 'informatif' tanpa seleksi atau arahkan kursor, tetapi ListViewItem memiliki tombol di dalamnya yang saya ingin agar dapat diklik dan diarahkan ke atas.

Jadi, sebenarnya yang saya inginkan adalah ListViewItem sama sekali bukan ListViewItem, Jadi, saya menaiki ControlTemplate ListViewItem dan membuatnya menjadi ContentControl sederhana.

<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>
Bradley Burnside
sumber
5

Salah satu properti listview adalah IsHitTestVisible. Hapus centangnya.

Jacob Levertov
sumber
Sederhana dan efektif, juga memecahkan masalah saya dengan ScrollViewer dibungkus tampilan daftar.
Brian Ng
1
Saya punya template tombol di dalam itemtemplate listview. jika batal pilih IsHitTestVisibletombol tidak dapat diklik. Ini bertindak sepertiIsEnabled = false;
Luiey
1

Ini untuk orang lain yang mungkin mengalami persyaratan berikut:

  1. Sepenuhnya mengganti indikasi visual "dipilih" (misalnya, menggunakan beberapa jenis bentuk), lebih dari sekadar mengubah warna sorotan standar
  2. Sertakan indikasi yang dipilih ini dalam DataTemplate bersama dengan representasi visual lainnya dari model Anda, tetapi,
  3. Tidak ingin menambahkan properti "IsSelectedItem" ke kelas model Anda dan dibebani dengan manipulasi properti secara manual pada semua objek model.
  4. Mengharuskan item untuk dapat dipilih di ListView
  5. Juga ingin mengganti representasi visual IsMouseOver

Jika Anda seperti saya (menggunakan WPF dengan .NET 4.5) dan menemukan bahwa solusi yang melibatkan pemicu gaya tidak berfungsi, inilah solusi saya:

Ganti ControlTemplate dari ListViewItem dengan gaya:

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

..Dan 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>

Hasil ini pada saat runtime (item 'B' dipilih, item 'D' memiliki mouse):

Tampilan ListView

BCA
sumber
1

Gunakan kode di bawah ini:

   <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>
Jorge Freitas
sumber
0

Kode di bawah menonaktifkan pemilihan baris ListViewItem dan juga memungkinkan untuk menambahkan padding, margin, dll.

<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> 
Saikat Chakraborty
sumber
0

Di bawah kode nonaktifkan Fokus pada 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>

mincasoft.dll
sumber