ฉันจะปิดการใช้งานการเลือกในกล่องรายการได้อย่างไร
ฉันจะปิดการใช้งานการเลือกในกล่องรายการได้อย่างไร
คำตอบ:
ItemsControl
ถ้าคุณไม่ต้องการแง่มุมอื่น ๆ ของListBox
คุณสามารถใช้ItemsControl
แทน มันวางรายการในItemsPanel
และไม่มีแนวคิดในการเลือก
<ItemsControl ItemsSource="{Binding MyItems}" />
ตามค่าเริ่มต้นItemsControl
ไม่รองรับการจำลองเสมือนขององค์ประกอบลูก หากคุณมีมากของรายการเสมือนจริงสามารถลดการใช้หน่วยความจำและปรับปรุงประสิทธิภาพการทำงานซึ่งในกรณีนี้คุณสามารถใช้วิธีการที่ 2 และรูปแบบListBox
หรือเพิ่มระบบเสมือนจริงที่คุณItemsControl
ListBox
หรือเพียงแค่กำหนดสไตล์กล่องรายการเพื่อไม่ให้มองเห็นสิ่งที่เลือก
<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
จะลบแนวคิดการเลือกใด ๆ
ฉันพบวิธีแก้ปัญหาที่ง่ายและตรงไปตรงมาทำงานให้ฉันฉันหวังว่ามันจะทำเพื่อคุณเช่นกัน
<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" />
คุณสามารถสลับไปใช้แทนItemsControl
มีแนวคิดของการเลือกไม่ดังนั้นไม่มีอะไรที่จะปิดเป็นListBox
ItemsControl
ItemTemplate
ใช่มันจะและนอกจากนี้คุณสามารถตั้งค่าด้วยตนเอง
ตัวเลือกอื่นที่ควรพิจารณาคือปิดการใช้งาน ListBoxItems สิ่งนี้สามารถทำได้โดยการตั้งค่า ItemContainerStyle ดังแสดงในตัวอย่างต่อไปนี้
<ListBox ItemsSource="{Binding YourCollection}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsEnabled" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
หากคุณไม่ต้องการให้ข้อความเป็นสีเทาคุณสามารถระบุสีที่ปิดใช้งานได้โดยเพิ่มแปรงลงในทรัพยากรของสไตล์ด้วยปุ่มต่อไปนี้: {x: Static SystemColors.GrayTextBrushKey} โซลูชันอื่นจะแทนที่แม่แบบการควบคุม ListBoxItem
สิ่งนี้จะใช้งานได้หากฉันต้องการใช้กล่องรายการแทน itemscontrol แต่ฉันกำลังแสดงรายการที่ไม่ควรเลือกได้ฉันใช้:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsHitTestVisible" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
คำตอบที่ดีค่อนข้างที่นี่ แต่ฉันกำลังมองหาบางสิ่งที่แตกต่างออกไปเล็กน้อย: ฉันต้องการการเลือก แต่ไม่ต้องการให้แสดง (หรือแสดงในเรื่องอื่น)
การแก้ปัญหาข้างต้นไม่ได้ผลสำหรับฉัน (สมบูรณ์) ดังนั้นฉันจึงทำอย่างอื่น: ฉันใช้รูปแบบใหม่สำหรับกล่องรายการของฉันซึ่งกำหนดแม่แบบใหม่ทั้งหมด:
<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>
เริ่มต้นด้วยสิ่งนั้นคุณสามารถเพิ่มการเน้นตัวเลือกของคุณเองหรือปล่อยไว้อย่างนั้นถ้าคุณไม่ต้องการอะไรเลย
ในขณะที่คำตอบของ @Drew Noakes เป็นทางออกที่รวดเร็วสำหรับกรณีส่วนใหญ่มีข้อบกพร่องเล็กน้อยที่มาพร้อมกับการตั้งค่า x: แปรงแบบคงที่
เมื่อคุณตั้งค่า x: แปรงแบบคงที่ตามที่แนะนำตัวควบคุมลูกทั้งหมดภายในรายการกล่องรายการจะได้รับลักษณะนี้
ซึ่งหมายความว่าในขณะนี้จะใช้งานได้สำหรับการปิดใช้งานการเน้นรายการกล่องรายการ แต่อาจส่งผลให้เกิดการควบคุมลูกที่ไม่พึงประสงค์
ตัวอย่างเช่นถ้าคุณมี ComboBox ภายใน ListBoxItem ของคุณมันจะปิดการใช้งานเมาส์เหนือการเน้นภายใน ComboBox
แต่พิจารณาตั้ง VisualStates สำหรับการเลือกเหตุการณ์ที่ไม่ได้เลือกและ MouseOver เป็นครอบคลุมในการแก้ปัญหาดังกล่าวในหัวข้อ StackOverflow นี้: ลบ Control Highlight จาก ListBoxItem แต่ไม่ควบคุมเด็ก
-Frinny
ฉันเสนอวิธีแก้ปัญหาอื่น เพียงแค่สร้างเทมเพลตใหม่ListBoxItem
เพื่อไม่ContentPresenter
ให้เป็น ...
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
เหตุผลของฉันสำหรับวิธีนี้มีดังนี้:
ในกรณีของฉันฉันไม่ต้องการปิดการใช้งานการโต้ตอบกับผู้ใช้กับเนื้อหาของฉันListBoxItems
ดังนั้นการตั้งค่าIsEnabled
จะไม่ทำงานสำหรับฉัน
โซลูชันอื่นที่พยายามจัดรูปแบบใหม่ListBoxItem
โดยการแทนที่คุณสมบัติที่เกี่ยวข้องกับสีจะทำงานเฉพาะกับอินสแตนซ์เหล่านั้นซึ่งคุณมั่นใจว่าแม่แบบนั้นใช้คุณสมบัติเหล่านั้น ไม่เป็นไรสำหรับรูปแบบเริ่มต้น แต่แบ่งกับสไตล์ที่กำหนดเอง
การแก้ปัญหาที่ใช้ItemsControl
สิ่งอื่น ๆ แบ่งมากเกินไปในขณะที่ItemsControl
มีรูปลักษณ์ที่แตกต่างอย่างสิ้นเชิงกว่ามาตรฐานListBox
และไม่สนับสนุนการทำงานแบบเสมือนซึ่งหมายความว่าคุณต้องอีกครั้งแม่แบบItemsPanel
อยู่แล้ว
ข้างต้นจะไม่เปลี่ยนรูปลักษณ์เริ่มต้นของListBox
ไม่ปิดใช้งานรายการในเทมเพลตข้อมูลสำหรับListBox
สนับสนุนการจำลองเสมือนโดยค่าเริ่มต้นและทำงานโดยไม่ขึ้นกับสไตล์ใดก็ตามที่อาจมีหรือไม่มีการใช้งานในแอปของคุณ มันเป็นหลักการจูบ
หมายเหตุ: วิธีนี้จะไม่ปิดใช้งานการเลือกโดยการนำทางด้วยแป้นพิมพ์หรือคลิกขวา (เช่นปุ่มลูกศรตามด้วยปุ่มเว้นวรรค)
คำตอบก่อนหน้านี้ทั้งหมดลบความสามารถในการเลือกอย่างสมบูรณ์ (ไม่มีการสลับในรันไทม์) หรือเพียงแค่ลบเอฟเฟกต์ภาพ แต่ไม่ใช่การเลือก
แต่ถ้าคุณต้องการให้สามารถเลือกและแสดงรายการที่เลือกตามรหัส แต่ไม่ใช่จากการป้อนข้อมูลของผู้ใช้ คุณอาจต้องการ "หยุด" การเลือกของผู้ใช้ในขณะที่ไม่ปิดการใช้งานกล่องรายการทั้งหมดหรือไม่
วิธีแก้คือห่อทั้ง ItemsContentTemplate ให้เป็นปุ่มที่ไม่มีโครเมียมแบบภาพ ขนาดของปุ่มจะต้องเท่ากับขนาดของรายการดังนั้นจึงครอบคลุมอย่างสมบูรณ์ ตอนนี้ใช้คุณสมบัติ IsEnabled ของปุ่ม:
เปิดใช้งานปุ่มเพื่อ "หยุด" สถานะการเลือกของรายการ วิธีนี้ใช้งานได้เนื่องจากปุ่มเปิดใช้งานจะกินเหตุการณ์ของเมาส์ทั้งหมดก่อนที่จะเพิ่มรายการไปยัง ListboxItem-Eventhandler ItemsDataTemplate ของคุณจะยังคงรับ MouseEvents เนื่องจากเป็นส่วนหนึ่งของเนื้อหาปุ่ม
ปิดใช้งานปุ่มเพื่อเปิดใช้งานการเปลี่ยนแปลงการเลือกโดยคลิก
<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
บางทีคุณอาจต้องการฟังก์ชั่นเฉพาะของ ItemsControl? ไม่อนุญาตให้เลือก:
<ItemsControl ItemsSource="{Binding Prop1}" ItemTemplate="{StaticResource DataItemsTemplate}" />
คุณสามารถวาง Textblock ด้านบนกล่องรายการของคุณมันจะไม่เปลี่ยนรูปลักษณ์ของแอปพลิเคชันของคุณและจะไม่อนุญาตให้เลือกรายการใด ๆ
อินสแตนซ์ของการแก้ไขอย่างง่าย ๆ ที่ทำงานบน Windows Phone นั้นอยู่ที่การเลือกรายการที่เลือกเป็นค่าว่าง:
<ListBox SelectionChanged="ListBox_SelectionChanged">
และในรหัสที่อยู่เบื้องหลัง:
private void ListBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
(sender as ListBox).SelectedItem = null;
}
ฉันพบวิธีที่สมบูรณ์แบบ
ชุดกล่องรายการ IsHitTestVisible เป็นเท็จเพื่อให้ผู้ใช้ไม่สามารถเลื่อนเมาส์หรือเลื่อนลงหรือเลื่อนขึ้น
จับภาพ PreviewGotKeyboardFocus e.Handled = true เพื่อให้ผู้ใช้สามารถเลือกรายการด้วยแท็บแป้นพิมพ์ลูกศรขึ้นลูกศรลง
วิธีนี้ได้เปรียบ:
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>
รหัส
private void StudentsListBox_PreviewGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
e.Handled = true;
}
สำหรับฉันทางออกที่ดีที่สุดคือ:
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Focusable" Value="True"/>
<Setter Property="IsHitTestVisible" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
IsEnabled = false
หากต้องการปิดการใช้งานหนึ่งตัวเลือกขึ้นไปใน listbox / dropdown ของคุณคุณสามารถเพิ่มแอตทริบิวต์ "disabled" ตามที่แสดงด้านล่าง วิธีนี้ป้องกันผู้ใช้จากการเลือกตัวเลือกนี้และได้รับการซ้อนทับสีเทา
ListItem item = new ListItem(yourvalue, yourkey);
item.Attributes.Add("disabled","disabled");
lb1.Items.Add(item);