Làm cách nào để tắt lựa chọn trong ListBox?
Làm cách nào để tắt lựa chọn trong ListBox?
Câu trả lời:
ItemsControl
Trừ khi bạn cần các khía cạnh khác của ListBox
, ItemsControl
thay vào đó , bạn có thể sử dụng . Nó đặt các mục trong ItemsPanel
và không có khái niệm lựa chọn.
<ItemsControl ItemsSource="{Binding MyItems}" />
Theo mặc định, ItemsControl
không hỗ trợ ảo hóa các phần tử con của nó. Nếu bạn có nhiều mục, ảo hóa có thể giảm mức sử dụng bộ nhớ và cải thiện hiệu suất, trong trường hợp đó bạn có thể sử dụng phương pháp 2 và tạo kiểu ListBox
hoặc thêm ảo hóa vàoItemsControl
.
ListBox
Ngoài ra, chỉ cần tạo kiểu cho ListBox sao cho lựa chọn không hiển thị.
<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>
ItemsControl
sẽ loại bỏ hoàn toàn bất kỳ khái niệm lựa chọn.
Tôi tìm thấy một giải pháp rất đơn giản và thẳng tiến làm việc cho tôi, tôi hy vọng nó cũng sẽ làm cho bạn
<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" />
Bạn có thể chuyển sang sử dụng ItemsControl
thay vì a ListBox
. An ItemsControl
không có khái niệm về lựa chọn, vì vậy không có gì để tắt.
ItemTemplate
.
Một tùy chọn khác đáng xem xét là vô hiệu hóa ListBoxItems. Điều này có thể được thực hiện bằng cách đặt ItemContainerStyle như trong đoạn trích sau.
<ListBox ItemsSource="{Binding YourCollection}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsEnabled" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Nếu bạn không muốn văn bản có màu xám, bạn có thể chỉ định màu bị tắt bằng cách thêm một cọ vào tài nguyên của kiểu bằng khóa sau: {x: Tĩnh SystemColors.GrayTextBrushKey}. Giải pháp khác là ghi đè lên mẫu điều khiển ListBoxItem.
Điều này cũng sẽ hoạt động, nếu tôi có nhu cầu sử dụng listbox thay vì các mục điều khiển, nhưng tôi chỉ hiển thị các mục không thể chọn, tôi sử dụng:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsHitTestVisible" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
Khá nhiều câu trả lời hay ở đây, nhưng tôi đang tìm kiếm một điều hơi khác: tôi muốn lựa chọn, nhưng chỉ không muốn nó được hiển thị (hoặc hiển thị trong một vấn đề khác).
Các giải pháp ở trên không hiệu quả với tôi (hoàn toàn), vì vậy tôi đã làm một việc khác: Tôi đã sử dụng một kiểu mới cho hộp danh sách của mình, định nghĩa lại hoàn toàn các mẫu:
<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>
Bắt đầu với điều đó, bạn có thể dễ dàng thêm phần tô sáng lựa chọn của riêng bạn hoặc để nó như thế nếu bạn không muốn chút nào.
Mặc dù câu trả lời của @Drew Noakes là một giải pháp nhanh chóng cho hầu hết các trường hợp, có một chút sai sót khi cài đặt các bàn chải x: Tĩnh.
Khi bạn đặt các bàn chải x: Tĩnh như được đề xuất, tất cả các điều khiển con trong mục hộp danh sách sẽ kế thừa kiểu này.
Điều đó có nghĩa là, trong khi điều này sẽ hoạt động để vô hiệu hóa phần tô sáng của mục hộp danh sách, nó có thể dẫn đến các hiệu ứng không mong muốn cho các điều khiển con.
Ví dụ: nếu bạn có ComboBox trong ListBoxItem, nó sẽ vô hiệu hóa chuột trên phần tô sáng trong ComboBox.
Thay vào đó, hãy xem xét việc thiết lập VisualStates cho các sự kiện đã chọn, không được chọn và MouseOver như được đề cập trong giải pháp được đề cập trong luồng stackoverflow này: Xóa Control Highlight khỏi ListBoxItem nhưng không điều khiển con .
-Frinny
Tôi đề xuất một giải pháp khác. Đơn giản chỉ cần đặt lại mẫu ListBoxItem
để không có gì hơn một ContentPresenter
, như vậy ...
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Lý do của tôi cho cách tiếp cận này là như sau:
Trong trường hợp của tôi, tôi không muốn vô hiệu hóa tương tác của người dùng với nội dung của mình ListBoxItems
để giải pháp thiết lập IsEnabled
sẽ không hiệu quả với tôi.
Giải pháp khác cố gắng định kiểu lại ListBoxItem
bằng cách ghi đè các thuộc tính liên quan đến màu sắc chỉ hoạt động cho những trường hợp mà bạn chắc chắn mẫu sử dụng các thuộc tính đó. Điều đó tốt cho các kiểu mặc định, nhưng phá vỡ các kiểu tùy chỉnh.
Các giải pháp sử dụng ItemsControl
phá vỡ quá nhiều thứ khác vì nó ItemsControl
có giao diện hoàn toàn khác so với tiêu chuẩn ListBox
và không hỗ trợ ảo hóa, nghĩa là bạn phải tạo lại mẫu bằng ItemsPanel
mọi cách.
Ở trên không thay đổi giao diện mặc định của ListBox
, không vô hiệu hóa các mục trong các mẫu dữ liệu cho ListBox
, hỗ trợ ảo hóa theo mặc định và hoạt động độc lập với bất kỳ kiểu nào có thể hoặc không được sử dụng trong ứng dụng của bạn. Đó là nguyên tắc KISS.
Lưu ý: Giải pháp này không vô hiệu hóa lựa chọn bằng điều hướng bàn phím hoặc nhấp chuột phải (ví dụ: phím mũi tên theo sau là phím cách)
Tất cả các câu trả lời trước đó đều loại bỏ khả năng chọn hoàn toàn (không chuyển đổi trong thời gian chạy) hoặc đơn giản là loại bỏ hiệu ứng hình ảnh, nhưng không loại bỏ lựa chọn.
Nhưng nếu bạn muốn có thể chọn và hiển thị lựa chọn theo mã, nhưng không phải bằng đầu vào của người dùng thì sao? Có thể bạn muốn "đóng băng" lựa chọn của người dùng trong khi không vô hiệu hóa toàn bộ Listbox?
Giải pháp là bọc toàn bộ ItemContentTemplate vào một Nút không có chrome trực quan. Kích thước của nút phải bằng kích thước của Vật phẩm, vì vậy nó được bao phủ hoàn toàn. Bây giờ sử dụng IsEnables-property của nút:
Kích hoạt nút "đóng băng" trạng thái Lựa chọn của vật phẩm. Điều này hoạt động vì nút được kích hoạt ăn tất cả các sự kiện chuột trước khi chúng nổi lên với ListboxItem-Eventhandler. ItemDataTemplate của bạn vẫn sẽ nhận được MouseEvents vì đây là một phần của nội dung các nút.
Vô hiệu hóa nút để cho phép thay đổi lựa chọn bằng cách nhấp vào.
<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>
phi tiêu
Có lẽ bạn cần chức năng onlly của ItemControl? Nó không cho phép lựa chọn:
<ItemsControl ItemsSource="{Binding Prop1}" ItemTemplate="{StaticResource DataItemsTemplate}" />
Một sửa chữa đơn giản hoạt động trên Windows Phone chẳng hạn là trên cài đặt lựa chọn mục đã chọn thành null:
<ListBox SelectionChanged="ListBox_SelectionChanged">
Và trong mã phía sau:
private void ListBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
(sender as ListBox).SelectedItem = null;
}
Tôi tìm thấy một cách hoàn hảo.
Đặt ListBox IsHitTestVisible thành false để người dùng không thể di chuột hoặc cuộn xuống hoặc cuộn lên.
Chụp bản xem trướcGotPalF Focus e.Handled = true để người dùng có thể chọn mục bằng Tab bàn phím, Mũi tên lên, Mũi tên xuống.
Cách này lợi thế:
xody
<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>
mã
private void StudentsListBox_PreviewGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
e.Handled = true;
}
Đối với tôi giải pháp tốt nhất là:
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Focusable" Value="True"/>
<Setter Property="IsHitTestVisible" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
IsEnables = false
Để vô hiệu hóa một hoặc nhiều tùy chọn trong hộp danh sách / thả xuống của bạn, bạn có thể thêm thuộc tính "bị vô hiệu hóa" như hiển thị bên dưới. Điều này ngăn người dùng chọn tùy chọn này và nó có lớp phủ màu xám.
ListItem item = new ListItem(yourvalue, yourkey);
item.Attributes.Add("disabled","disabled");
lb1.Items.Add(item);