Jak mogę wyłączyć zaznaczenie w ListBox?
Jak mogę wyłączyć zaznaczenie w ListBox?
Odpowiedzi:
ItemsControlO ile nie potrzebujesz innych aspektów ListBox, możesz ItemsControlzamiast tego użyć . Umieszcza przedmioty w ItemsPaneli nie ma pojęcia wyboru.
<ItemsControl ItemsSource="{Binding MyItems}" />
Domyślnie ItemsControlnie obsługuje wirtualizacji jego elementów potomnych. Jeśli masz wiele elementów, wirtualizacja może zmniejszyć zużycie pamięci i poprawić wydajność, w takim przypadku możesz zastosować podejście 2 i stylizować ListBoxlub dodać wirtualizację do swojegoItemsControl .
ListBoxAlternatywnie po prostu nadaj stylu ListBox tak, aby zaznaczenie nie było widoczne.
<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>
ItemsControlcałkowicie usunie każdą koncepcję selekcji.
Znalazłem bardzo proste i proste rozwiązanie, które działa dla mnie, mam nadzieję, że przydałoby się również Tobie
<ListBox ItemsSource="{Items}">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Focusable" Value="False"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Focusable = "False"!
<Setter Property="IsHitTestVisible" Value="False" />
Możesz przełączyć się na używanie ItemsControlzamiast zamiast ListBox. Nie ItemsControlma pojęcia selekcji, więc nie ma się co wyłączać.
ItemTemplate.
Inną opcją wartą rozważenia jest wyłączenie ListBoxItems. Można to zrobić, ustawiając ItemContainerStyle, jak pokazano w poniższym fragmencie.
<ListBox ItemsSource="{Binding YourCollection}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsEnabled" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Jeśli nie chcesz, aby tekst był szary, możesz określić wyłączony kolor, dodając pędzel do zasobów stylu za pomocą następującego klucza: {x: Static SystemColors.GrayTextBrushKey}. Innym rozwiązaniem byłoby zastąpienie szablonu kontrolnego ListBoxItem.
To również zadziała, jeśli będę musiał użyć pola listy zamiast kontroli przedmiotów, ale po prostu wyświetlę elementy, których nie można wybrać, używam:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsHitTestVisible" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
Dość dobre odpowiedzi tutaj, ale szukałem czegoś nieco innego: chcę selekcji, ale po prostu nie chcę, aby była pokazywana (lub pokazywana w innej sprawie).
Powyższe rozwiązania nie działały dla mnie (całkowicie), więc zrobiłem coś innego: użyłem nowego stylu dla mojego listbox, który całkowicie redefiniuje szablony:
<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>
Zaczynając od tego, możesz łatwo dodać własne zaznaczenie wyboru lub zostawić tak, jeśli w ogóle nie chcesz.
Podczas gdy odpowiedź @Drew Noakes jest szybkim rozwiązaniem w większości przypadków, istnieje pewna wada związana z ustawieniem pędzli x: Static.
Po ustawieniu pędzli x: Static zgodnie z sugestią wszystkie elementy podrzędne w elemencie pola listy odziedziczą ten styl.
Oznacza to, że chociaż będzie to działać w celu wyłączenia podświetlenia elementu listy, może to powodować niepożądane efekty dla elementów podrzędnych.
Na przykład, jeśli masz ComboBox w swoim ListBoxItem, to wyłączy to mysz nad podświetlaniem w ComboBox.
Zamiast tego zastanów się nad ustawieniem VisualStates dla zdarzeń Selected, Unselected i MouseOver zgodnie z rozwiązaniem wymienionym w tym wątku: „ Usuń wyróżnienie kontrolki z ListBoxItem, ale nie kontrolki potomne .
-Frinny
Proponuję jeszcze jedno rozwiązanie. Po prostu ponownie szablon, ListBoxItemaby był niczym więcej ContentPresenter, jak ...
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Moje powody takiego podejścia są następujące:
W moim przypadku nie chcę wyłączać interakcji użytkownika z zawartością mojego, ListBoxItemswięc ustawione rozwiązanie IsEnablednie będzie dla mnie działać.
Inne rozwiązanie, które próbuje zmienić styl ListBoxItem, zastępując właściwości związane z kolorem, działa tylko w tych przypadkach, w których masz pewność, że szablon używa tych właściwości. To jest w porządku dla stylów domyślnych, ale zrywa ze stylami niestandardowymi.
Rozwiązania, które wykorzystują ItemsControlzłamanie zbyt wielu innych rzeczy, ponieważ ItemsControlmają zupełnie inny wygląd niż standard ListBoxi nie obsługują wirtualizacji, co oznacza, że i tak musisz ponownie utworzyć szablon ItemsPanel.
Powyższe nie zmienia domyślnego wyglądu ListBox, nie wyłącza elementów w szablonach danych dla ListBox, domyślnie obsługuje wirtualizację i działa niezależnie od stylów, które mogą być lub nie być używane w Twojej aplikacji. To zasada KISS.
Uwaga: to rozwiązanie nie wyłącza wyboru poprzez nawigację na klawiaturze lub kliknięcie prawym przyciskiem (tj. Klawisze strzałek, a następnie klawisz spacji)
Wszystkie poprzednie odpowiedzi albo całkowicie usuwają wybór zdolności (bez przełączania w czasie wykonywania), albo po prostu usuwają efekt wizualny, ale nie wybór.
Ale co jeśli chcesz mieć możliwość wyboru i pokazania wyboru według kodu, ale nie na podstawie danych wprowadzonych przez użytkownika? Może chcesz „zamrozić” wybór użytkownika, nie wyłączając całego Listbox?
Rozwiązaniem jest zawinięcie całego ItemsContentTemplate w przycisk, który nie ma wizualnego chromu. Rozmiar przycisku musi być równy rozmiarowi przedmiotu, więc jest całkowicie zakryty. Teraz użyj właściwości IsEnabled przycisku:
Włącz przycisk, aby „zamrozić” stan zaznaczenia elementu. Działa to, ponieważ włączony przycisk zjada wszystkie zdarzenia myszy, zanim zostaną one bąbelkowane do modułu obsługi ListboxItem-Event. Twój ItemsDataTemplate nadal będzie otrzymywać MouseEvents, ponieważ jest częścią zawartości przycisków.
Wyłącz przycisk, aby włączyć zmianę zaznaczenia, klikając.
<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>
dartrax
Może potrzebujesz tylko funkcjonalności ItemsControl? Nie pozwala na wybór:
<ItemsControl ItemsSource="{Binding Prop1}" ItemTemplate="{StaticResource DataItemsTemplate}" />
Prosta poprawka, która działa na przykład na Windows Phone, polega na ustawieniu zaznaczenia wybranego elementu na zero:
<ListBox SelectionChanged="ListBox_SelectionChanged">
A w kodzie za:
private void ListBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
(sender as ListBox).SelectedItem = null;
}
Znalazłem idealny sposób.
Ustaw ListBox IsHitTestVisible na wartość false, aby użytkownik nie mógł najechać myszą, przewinąć w dół ani w górę.
Przechwyć PreviewGotKeyboardFocus e.Handled = true, aby użytkownik mógł wybrać element za pomocą klawiatury, Strzałka w górę, Strzałka w dół.
Zaleta w ten sposób:
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>
kod
private void StudentsListBox_PreviewGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
e.Handled = true;
}
Dla mnie najlepszym rozwiązaniem jest:
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Focusable" Value="True"/>
<Setter Property="IsHitTestVisible" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
IsEnabled = false
Aby wyłączyć jedną lub więcej opcji w liście / menu rozwijanym, możesz dodać atrybut „disabled”, jak pokazano poniżej. Zapobiega to wybraniu tej opcji przez użytkownika i uzyskuje szarą nakładkę.
ListItem item = new ListItem(yourvalue, yourkey);
item.Attributes.Add("disabled","disabled");
lb1.Items.Add(item);