ListBoxでの選択を無効にするにはどうすればよいですか?
ListBoxでの選択を無効にするにはどうすればよいですか?
回答:
ItemsControl
の他の側面が必要でない限りListBox
、ItemsControl
代わりに使用できます。アイテムをに配置し、ItemsPanel
選択の概念はありません。
<ItemsControl ItemsSource="{Binding MyItems}" />
デフォルトでItemsControl
は、その子要素の仮想化をサポートしていません。アイテムが多い場合、仮想化によりメモリ使用量を削減してパフォーマンスを向上させることができます。その場合、アプローチ2を使用してをスタイル設定しListBox
たり、仮想化をに追加しItemsControl
たりできます。
ListBox
または、選択が表示されないように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コントロールテンプレートをオーバーライドすることです。
ここではかなり良い答えですが、少し違うものを探していました。選択したいのですが、表示したくない(または別の問題で表示したくない)だけです。
上記の解決策は私には(完全に)うまくいかなかったので、私は別のことをしました:テンプレートを完全に再定義するリストボックスに新しいスタイルを使用しました:
<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:Staticブラシの設定に伴う欠点が少しあります。
x:Staticブラシを推奨どおりに設定すると、リストボックス項目内のすべての子コントロールがこのスタイルを継承します。
つまり、これはリストボックス項目の強調表示を無効にするために機能しますが、子コントロールに望ましくない影響が生じる可能性があります。
たとえば、ListBoxItem内にComboBoxがある場合、ComboBox内でのマウスオーバーの強調表示が無効になります。
代わりに、このstackoverflowのスレッドで言及した溶液中でカバーされて選択、非選択、およびマウスオーバーイベントのVisualStatesを設定することを検討:ListBoxItemではなく、子供たちのコントロールからの制御ハイライトを削除します。
-フリニー
さらに別の解決策を提案します。次のように、単に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
デフォルトで仮想化をサポートし、アプリで使用されているかどうかに関係なく、どのスタイルからも独立して機能します。それはKISSの原則です。
注:このソリューションは、キーボードナビゲーションまたは右クリックによる選択を無効にしません(つまり、矢印キーの後にスペースキーを押します)。
以前のすべての答えは、機能選択を完全に削除する(実行時に切り替えなし)か、単に選択ではなく視覚効果を削除するだけです。
しかし、ユーザー入力ではなくコードで選択を表示できるようにするにはどうすればよいでしょうか。リストボックス全体を無効にせずに、ユーザーの選択を「フリーズ」したいですか?
解決策は、ItemsContentTemplate全体をビジュアルクロームのないボタンにラップすることです。ボタンのサイズは、アイテムのサイズと同じでなければならないため、完全に覆われています。次に、ボタンのIsEnabled-Propertyを使用します。
ボタンを有効にして、アイテムの選択状態を「フリーズ」します。これが機能するのは、有効なボタンが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を配置できます。アプリケーションの外観は変更されず、アイテムを選択することもできません。
私は完璧な方法を見つけました。
ListBox IsHitTestVisibleをfalseに設定して、ユーザーがマウスをホバーしたり、下にスクロールしたり、上にスクロールしたりできないようにします。
Capture PreviewGotKeyboardFocus e.Handled = trueをキャプチャして、ユーザーがキーボードのTab、上矢印、下矢印でアイテムを選択できるようにします。
この方法の利点:
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
リストボックス/ドロップダウンで1つ以上のオプションを無効にするには、以下に示すように「無効」属性を追加できます。これにより、ユーザーがこのオプションを選択できなくなり、灰色のオーバーレイが表示されます。
ListItem item = new ListItem(yourvalue, yourkey);
item.Attributes.Add("disabled","disabled");
lb1.Items.Add(item);