Czy możesz podać przykład, w którym można mieć ListBox, z którego nie można wybrać? Ponieważ głównym zachowaniem jest wybieranie przedmiotów. Prawdopodobnie wybrałbym inny sposób, aby to pokazać. (To nie ja staram się być krytykiem, ale szczerze interesuję się tym, gdzie może się to zdarzyć)
Marthin
3
@ Martin: na przykład, jeśli chcesz przeciągnąć zawartość z elementu listy - w tym przypadku prawdopodobnie nie jesteś zainteresowany wyborem tego elementu. RÓWNIEŻ: podczas przeciągania elementu: wybrany element listy zmienia się podczas przeciągania w polu listy - zobacz ten post stackoverflow.com/questions/7589142/...
Danield
1
Uważam, że powodem, dla którego Shimmy chce używać ListBox, jest to, że pytający może w pewnym momencie wybrać pole listy. To pytanie jest również dla mnie cenne. Załóżmy, że budujesz grę w karty. Możesz wybrać jedną kartę ze swoich kart, czasem możesz wybrać wiele, a innym razem nie możesz wybrać żadnej.
Gqqnbig,
1
Ponadto czasami masz 10 kart i tylko 4 z nich można wybierać. Wśród 4 możesz wybrać do 3.
Gqqnbig,
1
@Marthin: Gdy masz GridView w ListBox. Nagłówki Gridview zapewniają wiele funkcji niedostępnych gdzie indziej. I masz kontrolki edycji w komórkach widoku siatki.
Robin Davies,
Odpowiedzi:
264
Podejście 1 - ItemsControl
O ile nie potrzebujesz innych aspektów ListBox, możesz ItemsControlzamiast tego użyć . Umieszcza przedmioty w ItemsPaneli nie ma pojęcia wyboru.
<ItemsControlItemsSource="{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 .
Podejście 2 - Stylizacja ListBox
Alternatywnie po prostu nadaj stylu ListBox tak, aby zaznaczenie nie było widoczne.
<ListBox.Resources><StyleTargetType="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><SetterProperty="FocusVisualStyle"Value="{x:Null}"/></Style></ListBox.Resources>
nie, zmieni jedynie efekt wizualny, a nie faktyczne zachowanie selekcji
Thomas Levesque,
8
Moją pierwszą sugestią było użycie ItemsControl. Tęskniłeś za tym? :)
Drew Noakes,
5
Ponownie czytając te komentarze, chcę podkreślić, że komentarz @Thomas Levesque dotyczy tylko drugiego podejścia, które pokazuję. Użycie zwykłego ItemsControlcałkowicie usunie każdą koncepcję selekcji.
Drew Noakes,
1
Rozwiązanie ItemsControl usuwa obsługę przewijania pola (pasek przewijania i kółko myszy).
MuiBienCarlota
1
+1 za podejście 1 - ItemsControl. Jeśli mamy ogromną stronę, którą musimy przewinąć, jeśli użytkownik najedzie myszką na ListBox, to skutecznie wyłączy MouseWheel, gdy lista będzie przechwytywać zdarzenia MouseWheel. Oznacza to, że użytkownik jest sfrustrowany, że kółko myszy używane do przewijania całej strony losowo przestanie działać, w zależności od tego, czy wskaźnik myszy znajduje się nad polem listy, czy nie.
Contango,
159
Znalazłem bardzo proste i proste rozwiązanie, które działa dla mnie, mam nadzieję, że przydałoby się również Tobie
To jest doskonałe. zapobiega wybranemu elementowi i innym elementom sterującym, takim jak przyciski, nadal działa. dokładnie to, czego szukałem
Franck
1
+1 za to podejście. Jeśli mamy ogromną stronę, którą musimy przewinąć, jeśli użytkownik najedzie myszką na ListBox, to skutecznie wyłączy MouseWheel, gdy lista będzie przechwytywać zdarzenia MouseWheel. Oznacza to, że użytkownik jest sfrustrowany, że kółko myszy używane do przewijania całej strony losowo przestanie działać, w zależności od tego, czy wskaźnik myszy znajduje się nad polem listy, czy nie.
Contango,
Doskonały. Podobne podejście działało również dla mnie, gdy potrzebowałem przycisków na przedmiotach, aby nie powodować wyboru przedmiotu - ale tylko wtedy, gdy kliknięto inny obszar przedmiotu. Wystarczy ustawić przyciski Focusable = "False"!
Jony Adamit
1
Dodaj tę dodatkową właściwość, aby również usunąć wyróżnienie <Setter Property="IsHitTestVisible" Value="False" />
kursora
25
Możesz przełączyć się na używanie ItemsControlzamiast zamiast ListBox. Nie ItemsControlma pojęcia selekcji, więc nie ma się co wyłączać.
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.
Prosty i działający, dzięki! Dotyczy to również WP 8.1 Runtime.
Malutek
8
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:
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:
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.
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.
@Shimmy: Trywialne odpowiedzi są podobne. Nie ma tu powielania godnego żadnej flagi. Jeśli masz więcej pytań na ten temat, zadaj pytanie na temat Meta Stack Overflow .
0
Możesz umieścić blok tekstu nad listą, nie zmieni to wyglądu twojej aplikacji, a także nie pozwoli wybrać żadnego elementu.
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:
Elementy ListBox Pierwszy plan nie zmieni się na szary.
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ę.
Odpowiedzi:
Podejście 1 -
ItemsControl
O ile nie potrzebujesz innych aspektów
ListBox
, możeszItemsControl
zamiast tego użyć . Umieszcza przedmioty wItemsPanel
i nie ma pojęcia wyboru.Domyślnie
ItemsControl
nie 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ćListBox
lub dodać wirtualizację do swojegoItemsControl
.Podejście 2 - Stylizacja
ListBox
Alternatywnie po prostu nadaj stylu ListBox tak, aby zaznaczenie nie było widoczne.
źródło
ItemsControl
cał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
źródło
Focusable = "False"
!<Setter Property="IsHitTestVisible" Value="False" />
Możesz przełączyć się na używanie
ItemsControl
zamiast zamiastListBox
. NieItemsControl
ma pojęcia selekcji, więc nie ma się co wyłączać.źródło
ItemTemplate
.Inną opcją wartą rozważenia jest wyłączenie ListBoxItems. Można to zrobić, ustawiając ItemContainerStyle, jak pokazano w poniższym fragmencie.
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.
źródło
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:
źródło
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:
Zaczynając od tego, możesz łatwo dodać własne zaznaczenie wyboru lub zostawić tak, jeśli w ogóle nie chcesz.
źródło
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
źródło
Proponuję jeszcze jedno rozwiązanie. Po prostu ponownie szablon,
ListBoxItem
aby był niczym więcejContentPresenter
, jak ...Moje powody takiego podejścia są następujące:
W moim przypadku nie chcę wyłączać interakcji użytkownika z zawartością mojego,
ListBoxItems
więc ustawione rozwiązanieIsEnabled
nie 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ą
ItemsControl
złamanie zbyt wielu innych rzeczy, ponieważItemsControl
mają zupełnie inny wygląd niż standardListBox
i nie obsługują wirtualizacji, co oznacza, że i tak musisz ponownie utworzyć szablonItemsPanel
.Powyższe nie zmienia domyślnego wyglądu
ListBox
, nie wyłącza elementów w szablonach danych dlaListBox
, 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.źródło
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.
dartrax
źródło
Może potrzebujesz tylko funkcjonalności ItemsControl? Nie pozwala na wybór:
źródło
Możesz umieścić blok tekstu nad listą, nie zmieni to wyglądu twojej aplikacji, a także nie pozwoli wybrać żadnego elementu.
źródło
Prosta poprawka, która działa na przykład na Windows Phone, polega na ustawieniu zaznaczenia wybranego elementu na zero:
A w kodzie za:
źródło
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
kod
źródło
Dla mnie najlepszym rozwiązaniem jest:
źródło
IsEnabled = false
źródło
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ę.
źródło