WPF ListView seçimi kapat


122

Basit bir WPF ListView ve basit bir sorum var:

Seçimi kapatmak mümkün mü, böylece kullanıcı satırı tıkladığında satır vurgulanmıyor mu?

Liste görünümü

1. satırın tıklandığında aynı satır 0 gibi görünmesini istiyorum.

Muhtemelen ilişkili: Fareyle üzerine gelme / seçimin görünümünü şekillendirebilir miyim? Örneğin. mavi degrade vurgulu görünümü (3. satır) özel bir düz renkle değiştirmek için. Ben bulduk bu ve bu maalesef yardımcı olmuyor.

(ListView kullanmadan aynısını başarmak da kabul edilebilir. ListView gibi mantıksal kaydırmayı ve kullanıcı arayüzü sanallaştırmayı kullanabilmek istiyorum)

ListView için 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'de daha önce hiç ListView kullanmadım, ancak yanlış olarak ayarlanırsa tüm kontrolü devre dışı bırakacak ve muhtemelen peşinde olduğunuz şeyi elde edecek bir tür IsEnabled özelliği olduğundan eminim, ancak ben % 100 emin değilim.
James McConnell

Merhaba, evet, ListView'in tamamını devre dışı bırakabilen bir IsEnabled özelliği var. ListView'ın normal şekilde çalışmasına ihtiyacım var, sadece seçimi göstermeyin.
Martin Konicek

Yanıtlar:


137

Per Martin Konicek'in yorumu, öğelerin seçimini en basit şekilde tamamen devre dışı bırakmak için:

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

Ancak yine de ListView işlevselliğine ihtiyaç duyuyorsanız, örneğin bir öğeyi seçebilmek gibi, seçili öğenin stilini şu şekilde görsel olarak devre dışı bırakabilirsiniz:

Bunu, ListViewItem'in ControlTemplate'ini değiştirmekten yalnızca bir stil ayarlamaya (çok daha kolay) kadar çeşitli şekillerde yapabilirsiniz . ItemContainerStyle'ı kullanarak ListViewItems için bir stil oluşturabilir ve seçildiğinde arka planı ve kenarlık fırçasını 'kapatabilirsiniz'.

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

Ayrıca, öğe seçildiğinde (veya yalnızca test için) kullanıcıyı bilgilendirmenin başka bir yolu yoksa, değeri temsil edecek bir sütun ekleyebilirsiniz:

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

2
İlgili kısmı görmedim, ancak aynı şeyi, IsMouseOver özelliğinde istediğiniz gibi arka planı ve sınırı ayarlayarak yapabilirsiniz.
rmoore

88
Şimdi daha da iyi çözdüm - <Setter Property = "Focusable" Value = "false" />, satırı seçmeyi tamamen devre dışı bırakır.
Martin Konicek

8
Ahh, Seçimi görsel olarak kapatmaktan bahsettiğini sanıyordum. Bunların seçilmesini hiç istemiyorsanız, bir Öğeler Kontrolünü kullanarak bir göz atmak isteyebilirsiniz (Odaklanamazlarsa seçili öğeleri kod aracılığıyla yine de ayarlayabilirsiniz), ancak Kılavuzun size bakmasını sağlamak için Bunun gibi bir şey yapmanız gerekecek: manicprogrammer.com/cs/blogs/… Ayrıca, henüz yapmadıysanız, WPF & XAML için harika bir giriş sağladığı için WPF Unleashed kitabına göz atmak isteyebilirsiniz.
rmoore

2
@MartinKonicek bunun eski bir gönderi olduğunu biliyorum ancak yüksek puan alan yorumunuz bir cevap olmalı;)
WiiMaxx

1
@MartinKonicek ben eklemek zorunda BasedOn="{StaticResource {x:Type ListViewItem}}"benim ızgara tarzı kalanını geçersiz vermedi böylece, ama aynı zamanda size comment kabul cevabı yapmak gerektiğini düşünüyorum
JumpingJezza

31

Moore'un cevabı işe yaramıyor ve buradaki sayfa:

Liste Kutusundaki öğeler için Seçim Rengini, İçerik Hizalamasını ve Arka Plan Rengini Belirleme

neden çalışamayacağını açıklıyor.

Liste görünümünüz yalnızca temel metin içeriyorsa, sorunu çözmenin en basit yolu şeffaf fırçalar kullanmaktır.

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

Bu, liste görünümünün hücreleri, renklerini de değiştirdiği için, birleşik giriş kutuları gibi kontrolleri tutuyorsa istenmeyen sonuçlar üretecektir. Bu sorunu çözmek için, kontrol şablonunu yeniden tanımlamalısınız.

  <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
Bu, ListView'daki tüm öğelerimin kaybolmasına neden oluyor
Chuck Savage

18

Her ListViewItem stilini Focusable değerini false olarak ayarlayacak şekilde ayarlayın.

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

4
Basit ve verimli. Ve aslında isteneni yapıyor: Sadece gizlemek yerine seçimi kapatıyor. Bu en iyi cevap.
Fumidu

13

İşte Blend'den ListViewItem için varsayılan şablon:

Varsayılan ListViewItem Şablonu:

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

Varsayılan şablonu değiştirmek için aşağıdaki kodu Tarzınıza ekleyerek IsSelected Trigger ve IsSelected / IsSelectionActive MultiTrigger'ı kaldırın ve seçildiğinde görsel bir değişiklik olmayacaktır.

IsSelected özelliğinin görsel değişikliklerini kapatma çözümü:

    <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

Bulduğum en kolay yol:

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

4
@ Mutex İşe yarıyor - ListView.ItemContainerStyleyine de bunu uygulamanız gerekiyor !
Andreas Niedermair

8

Yukarıdaki çözüme ek olarak ... MouseOver vurgularının seçimden sonra çalışmaya devam etmesini sağlamak için bir MultiTrigger kullanırdım, öyle ki ListViewItem'inizin stili:

        <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

Tamam, oyuna biraz geç ama bu çözümlerin hiçbiri benim yapmaya çalıştığım şeyi tam olarak yapmadı. Bu çözümlerin birkaç sorunu var

  1. Stilleri mahveden ve tüm alt kontrolleri devre dışı bırakan ListViewItem'i devre dışı bırakın
  2. Vuruş testi yığınından kaldırın, yani alt kontroller hiçbir zaman fareyle üzerine gelmez veya tıklama almaz
  3. Odaklanmasın, bu benim için işe yaramadı mı?

Gruplama başlıklarına sahip bir ListView istedim ve her ListViewItem seçim olmadan veya üzerine gelmeden sadece 'bilgi amaçlı' olmalı, ancak ListViewItem'in içinde tıklanabilir ve üzerine gelmesini istediğim bir düğme var.

Yani, gerçekten istediğim, ListViewItem'in bir ListViewItem olmamasıdır, Bu yüzden ListViewItem'in ControlTemplate'ini aştım ve basit bir ContentControl yaptım.

<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

Liste görünümünün özelliklerinden biri IsHitTestVisible. İşaretini kaldırın.


Basit ve etkili, ayrıca ScrollViewer'ın liste görünümünün yanına sarılmasıyla sorunumu çöz.
Brian Ng

1
Liste görünümü öğe şablonunun içinde düğme şablonu var. seçimi kaldırırsanız IsHitTestVisibledüğme tıklanamaz. Gibi IsEnabled = false;
davran

1

Bu, aşağıdaki gereksinimleri karşılayabilecek diğer kişiler içindir:

  1. Standart vurgunun rengini değiştirmenin ötesinde, "seçilmiş" ifadesinin görsel göstergesini tamamen değiştirin (örneğin, bir tür şekil kullanın)
  2. Modelinizin diğer görsel temsilleriyle birlikte bu seçili gösterimi DataTemplate'e dahil edin, ancak,
  3. Model sınıfınıza bir "IsSelectedItem" özelliği eklemek ve bu özelliği tüm model nesnelerinde manuel olarak değiştirmek zorunda kalmak istemiyorum.
  4. ListView'da öğelerin seçilebilir olmasını zorunlu kılın
  5. Ayrıca IsMouseOver'ın görsel sunumunu değiştirmek istiyor

Benim gibiyseniz (.NET 4.5 ile WPF kullanarak) ve stil tetikleyicilerini içeren çözümlerin işe yaramadığını fark ettiyseniz, işte çözümüm:

ListViewItem'in ControlTemplate'ini bir stilde değiştirin: Replace the ControlTemplate of the ListViewItem in a style:

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

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

Çalışma zamanında bunun sonuçları ('B' öğesi seçilmiştir, 'D' öğesinin faresi üzerinde):

ListView görünümü


1

Aşağıdaki kodu kullanın:

   <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

Aşağıdaki kod, ListViewItem satır seçimini devre dışı bırakır ve ayrıca dolgu, kenar boşluğu vb. Eklemeye izin verir.

<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

Kodun altında ListViewItem'e Odağı devre dışı bırakın

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.