ListBox.SelectionMode =“ None”はありません。リストボックスでの選択を無効にする別の方法はありますか?


188

ListBoxでの選択を無効にするにはどうすればよいですか?


1
選択できないListBoxが有効である例を提供できますか?主な動作はアイテムを選択することなので。おそらく、別の方法で表示することを選択したでしょう(これは私が批評家になろうとしているのではなく、これが発生する可能性がある場所への純粋な関心です)
Marthin

3
@Martin:たとえば、リストボックスアイテムからコンテンツをドラッグしたい場合-この場合、おそらくそのアイテムを選択することに興味はありません。アイテムドラッグするとき::また、あなたがリストボックスの中にドラッグしながら、リストボックスの変更を選択した項目を-この記事を参照stackoverflow.com/questions/7589142/...
Danield

1
ShimmyがListBoxを使用したい理由は、質問者がリストボックスをいつでも選択できるようにすることができるためです。質問は私にとっても貴重です。トランプゲームを構築しているとします。カードから1枚のカードを選択できます。複数のカードを選択できる場合もあれば、何も選択できない場合もあります。
Gqqnbig

1
さらに、10枚のカードがあり、そのうち4枚しか選択できない場合もあります。4の中で、あなたは3まで選択することができます
Gqqnbig

1
@Marthin:ListBoxにGridViewがある場合。Gridviewヘッダーは、他では利用できない多くの機能を提供します。そして、グリッドビューのセルに編集コントロールがあります。
Robin Davies

回答:


264

アプローチ1- ItemsControl

の他の側面が必要でない限りListBoxItemsControl代わりに使用できます。アイテムをに配置し、ItemsPanel選択の概念はありません。

<ItemsControl ItemsSource="{Binding MyItems}" />

デフォルトでItemsControlは、その子要素の仮想化をサポートしていません。アイテムが多い場合、仮想化によりメモリ使用量を削減してパフォーマンスを向上させることができます。その場合、アプローチ2を使用してをスタイル設定しListBoxたり、仮想化をに追加しItemsControlたりできます

アプローチ2-スタイリング 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>

24
いいえ、実際の選択動作ではなく視覚効果のみが変更されます
Thomas Levesque

8
私の最初の提案は、ItemsControlを使用することでした。見逃しましたか?:)
Drew Noakes

5
これらのコメントをもう一度読んで、@ Thomas Levesqueのコメントは、私が示す2番目のアプローチにのみ当てはまることを指摘したいと思います。プレーンItemsControlを使用すると、選択の概念が完全に削除されます。
Drew Noakes、2011

1
ItemsControlソリューションは、ボックスのスクロールサポート(スクロールバーとマウスホイール)を削除します。
MuiBienCarlota 2013

1
アプローチ1の+1-ItemsControl。スクロールする必要のある大きなページがある場合、ユーザーがListBoxの上にマウスを置くと、リストボックスがMouseWheelイベントを取得するときに、MouseWheelを効果的に無効にします。これは、ページ全体をスクロールするために使用されるマウスホイールが、マウスがリストボックス上にあるかどうかに応じて、ランダムに機能しなくなることにユーザーが不満を感じることを意味します。
Contango、2015

159

私は非常にシンプルで簡単な解決策が私に役立つことを見つけました、それがあなたにも役立つことを願っています

<ListBox ItemsSource="{Items}">
    <ListBox.ItemContainerStyle>
       <Style TargetType="{x:Type ListBoxItem}">
           <Setter Property="Focusable" Value="False"/>
       </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

私は彼がここでそれをかなりうまく通過したと思います:asaddurrani.wordpress.com/tag/wpf-listbox-disable-selection
Sid

3
これは完璧です。選択したアイテムやボタンなどのその他のコントロールが機能しないようにします。まさに私が探していたもの
フランク

1
このアプローチの+1。スクロールする必要のある大きなページがある場合、ユーザーがListBoxの上にマウスを置くと、リストボックスがMouseWheelイベントを取得するときに、MouseWheelを効果的に無効にします。これは、ページ全体をスクロールするために使用されるマウスホイールが、マウスがリストボックス上にあるかどうかに応じて、ランダムに機能しなくなることにユーザーが不満を感じることを意味します。
Contango、2015

優れた。同様のアプローチは、アイテムの選択を引き起こさないようにアイテムのボタンが必要な場合にも機能しました。ただし、アイテムの他の領域がクリックされた場合のみです。ボタンをセットするだけFocusable = "False"
ジョニーアダミット16年

1
同様にマウスオーバーのハイライトを削除するには、この追加のプロパティを追加します <Setter Property="IsHitTestVisible" Value="False" />
DonBoitnott

25

ItemsControl代わりにを使用するように切り替えることができListBoxます。にItemsControlは選択の概念がないため、オフにするものはありません。


2
チャーミング。ItemsControlを直接宣言できることを知りませんでした。仮想(MustOverride)だと思いました。ありがとう!!!
Shimmy Weitzhandler 2009

しかし、ItemsControlは私のアイテムを1行でレンダリングしますか?
Chry Cheng

@Chryはい、そうしますItemTemplate。さらに、いつでも手動でを設定できます。
Shimmy Weitzhandler、

2
これにより、スクロールなどの機能が失われます。
ジェフ

@Jeffスクロールを取得するために、ScrollViewerでItemsControlをラップできます。
Wilka、2012

12

検討する価値のある別のオプションは、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コントロールテンプレートをオーバーライドすることです。


シンプルで機能している、ありがとう!また、WP 8.1ランタイムにも適用できます。
マルテック2014

8

これは、itemscontrolの代わりにリストボックスを使用する必要がある場合でも機能しますが、選択できないはずの項目を表示しているだけなので、次のように使用します。

<ListBox.ItemContainerStyle>
    <Style TargetType="ListBoxItem">
        <Setter Property="IsHitTestVisible" Value="False" />
    </Style>
</ListBox.ItemContainerStyle>

3

ここではかなり良い答えですが、少し違うものを探していました。選択したいのですが、表示したくない(または別の問題で表示したくない)だけです。

上記の解決策は私には(完全に)うまくいかなかったので、私は別のことをしました:テンプレートを完全に再定義するリストボックスに新しいスタイルを使用しました:

<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>

それから始めて、独自の選択の強調表示を簡単に追加したり、まったく必要ない場合はそのままにすることができます。


2

@Drew Noakesの答えはほとんどの場合の迅速な解決策ですが、x:Staticブラシの設定に伴う欠点が少しあります。

x:Staticブラシを推奨どおりに設定すると、リストボックス項目内のすべての子コントロールがこのスタイルを継承します。

つまり、これはリストボックス項目の強調表示を無効にするために機能しますが、子コントロールに望ましくない影響が生じる可能性があります。

たとえば、ListBoxItem内にComboBoxがある場合、ComboBox内でのマウスオーバーの強調表示が無効になります。

代わりに、このstackoverflowのスレッドで言及した溶液中でカバーされて選択、非選択、およびマウスオーバーイベントのVisualStatesを設定することを検討:ListBoxItemではなく、子供たちのコントロールからの制御ハイライトを削除します

-フリニー


2

さらに別の解決策を提案します。次のように、単にListBoxItemにすぎないように再テンプレートしますContentPresenter...

<Style TargetType="{x:Type ListBoxItem}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                <ContentPresenter />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

このアプローチの私の理由は次のとおりです。

  1. 私の場合、ユーザーのコンテンツとの対話を無効にしたくないListBoxItemsので、設定IsEnabledするソリューションが機能しません。

  2. ListBoxItem色に関連するプロパティをオーバーライドしてスタイルを再設定しようとする他のソリューションは、テンプレートがそれらのプロパティを使用していることが確実である場合にのみ機能します。これはデフォルトのスタイルでは問題ありませんが、カスタムスタイルでは機能しません。

  3. ItemsControlブレークを使用するソリューションは、ItemsControl標準外観がまったく異なりListBox、仮想化をサポートしていないため、ItemsPanelとにかく再テンプレートする必要があるため、が発生します。

上記はのデフォルトの外観を変更ListBoxせず、のデータテンプレートの項目を無効にしません。ListBoxデフォルトで仮想化をサポートし、アプリで使用されているかどうかに関係なく、どのスタイルからも独立して機能します。それはKISSの原則です。


1

注:このソリューションは、キーボードナビゲーションまたは右クリックによる選択を無効にしません(つまり、矢印キーの後にスペースキーを押します)。

以前のすべての答えは、機能選択を完全に削除する(実行時に切り替えなし)か、単に選択ではなく視覚効果を削除するだけです。

しかし、ユーザー入力ではなくコードで選択を表示できるようにするにはどうすればよいでしょうか。リストボックス全体を無効にせずに、ユーザーの選択を「フリーズ」したいですか?

解決策は、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


1

たぶん、あなたはItemsControlの機能だけを必要としますか?選択はできません:

<ItemsControl ItemsSource="{Binding Prop1}" ItemTemplate="{StaticResource DataItemsTemplate}" />

3
@シミー:些細な答えが似ていることは一般的です。ここでは、フラグに値する重複はありません。これについてさらに質問がある場合は、メタスタックオーバーフローで質問してください。

0

リストボックスの上にTextblockを配置できます。アプリケーションの外観は変更されず、アイテムを選択することもできません。


1
ただし、タブナビゲーションを無効にする必要があります。
Amanduh、2013

0

たとえばWindows Phoneで機能する簡単な修正は、選択された項目をnullに設定する選択です。

    <ListBox SelectionChanged="ListBox_SelectionChanged">

そして後ろのコードで:

    private void ListBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
    {
        (sender as ListBox).SelectedItem = null;
    }

0

私は完璧な方法を見つけました。
ListBox IsHitTestVisibleをfalseに設定して、ユーザーがマウスをホバーしたり、下にスクロールしたり、上にスクロールしたりできないようにします。
Capture PreviewGotKeyboardFocus e.Handled = trueをキャプチャして、ユーザーがキーボードのTab、上矢印、下矢印でアイテムを選択できるようにします。

この方法の利点:

  1. ListBoxアイテムのフォアグラウンドは灰色になりません。
  2. リストボックスの背景は透明に設定できます

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;
}

-1

私にとっての最善の解決策は:

        <ListBox.ItemContainerStyle>
            <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="Focusable" Value="True"/>
                <Setter Property="IsHitTestVisible" Value="False" />
            </Style>
        </ListBox.ItemContainerStyle>

-3

IsEnabled = false


2
それはすべて灰色になります、これは私が探しているものではありません
Shimmy Weitzhandler

1
しかし、それは簡単な質問に対する簡単な答えです:)
Viktor Jevdokimov

1
簡単な答えはこのstackoverflow.com/questions/1398559/1398650#1398650ですが、とにかく感謝します
Shimmy Weitzhandler 2010

私にとって非常に役立ちます。グレー表示になって無効にしたかったのです。
Martin Robins

-3

リストボックス/ドロップダウンで1つ以上のオプションを無効にするには、以下に示すように「無効」属性を追加できます。これにより、ユーザーがこのオプションを選択できなくなり、灰色のオーバーレイが表示されます。

ListItem item = new ListItem(yourvalue, yourkey);
item.Attributes.Add("disabled","disabled");
lb1.Items.Add(item);

そのとき、あなたは高くなり、ASP.NETソリューションでWPFの質問に答えました。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.