2

ユーザーが選択できない項目がいくつか含まれているリストボックスを作成しようとしています。グループ化されたリストボックスのグループ見出しを考えてみてください。ただし、これらは独立したアイテムです(つまり、インデントされた子はありません)。リストにメッセージを表示したいだけです。

これは、「Foo」アイテムがある場合に現在表示されているもののモックアップです...

Foo 1
Foo 2
Foo 3
--------------   <-- This is of type 'Separator' so it's styled as not-selectable by default.
Add new Foo...
Manage Foos...

...そしてFooアイテムがない場合は、これを表示します...

[No Foo Items]   <-- This one should not be selectable, the same as a separator
--------------   <-- This is of type 'Separator' so it's styled as not-selectable by default.
Add new Foo...
Manage Foos...

ここでも、表示内容を適切に処理するコードがすでに用意されています(以下を参照)。そのエントリを選択できないようにする適切な方法は何でしょうか。

私たちが知らないのは、そのListBoxItemのスタイルを設定して、選択がその上をスキップしたり、ユーザーがそれをクリックしたりできないようにする方法です。

コード

誰かが私のコードを見るように私に頼んだので、ここにあります。質問にはあまり関係ありませんが、私がこれをどのように行ったかを人々に示す必要があります。

注:string.Emptyローカライズされた「NoxxxItems」メッセージを表示するためにXAMLでテンプレートを作成します。 string.Emptyターゲットにできる単なるプレースホルダーです。

注2:FauxDataは、テストに使用されるアイテムとコレクションの単純なライブラリであるため、常に最初から作成する必要はありません。たとえば、SimpleItemCollectionは、コンストラクター内に10個のSimpleItemオブジェクトを作成し、Name、Description、IsSelectedなどが事前に入力されています。これらはすべてINotifyPropertyChangedおよびコレクション変更通知を完全にサポートしています。親、子、IsExpandedなどを追加するHierarchicalItemsCollectionでも同じことが言えます。これにより、コードとコントロールをテストする際の作業が大幅に節約されます。

最後に、これは単純なテスト、つまり「遊び場」アプリからのものです。そのため、概念を示すためだけに、物事を行うための最良の方法を表すものではありません。はい、それはたくさんきれいにすることができます、しかしあなたは一般的な考えを理解します。

とにかく、コードに...

using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using FauxData;

namespace Playground.ListTest
{
    [LaunchEntry("List Test")]
    public partial class Main : Window
    {
        SimpleItemCollection itemsCollection = new SimpleItemCollection(); // Default constructor creates 10 items

        public Main()
        {
            InitializeComponent();
            MainListBox.ItemsSource = CreateCompositeCollection();
        }

        private CompositeCollection CreateCompositeCollection()
        {
            var EmptyHolder = new ObservableCollection<object>();

            itemsCollection.CollectionChanged += (s,e) => {

                if(itemsCollection.Count != 0)
                    EmptyHolder.Clear();
                else if(EmptyHolder.Count == 0)
                    EmptyHolder.Add(string.Empty);

            };

            var cc = new CompositeCollection();

            cc.Add(new CollectionContainer(){ Collection = itemsCollection });
            cc.Add(new CollectionContainer(){ Collection = EmptyHolder });
            cc.Add(new Separator());
            cc.Add(ApplicationCommands.New);   // <-- Pops a dialog to enter a new item
            cc.Add(ApplicationCommands.Open);  // <-- Shows an item management window

            return cc;

        }

        private void Test_Click(object sender, RoutedEventArgs e)
        {
            if(itemsCollection.Count != 0)
                itemsCollection.Clear();
            else
                itemsCollection.Add(new SimpleItem(){Name = "New item" });
        }

    }

}
4

3 に答える 3

3

Focusable="false"すべてのオプション (クリック アンド ドラッグ選択など) を網羅しているわけではないので、代わりに を設定することをお勧めしIsEnabledますfalse

(グレーアウトされたテキストはListBoxItemスタイル/テンプレートの問題なので、気に入らない場合は上書きする必要があります)

于 2012-09-26T19:27:45.093 に答える
1

グレーアウトしたくない場合は、 IsHitTestVisible がそれを達成しているようです。

    <ListBox SelectionMode="Multiple">
        <ListBoxItem IsEnabled="False">HEsder</ListBoxItem>
        <ListBoxItem IsEnabled="True">1</ListBoxItem>
        <ListBoxItem IsHitTestVisible="False">-----</ListBoxItem>
        <ListBoxItem IsEnabled="True">2</ListBoxItem>
    </ListBox>

バインドしている場合は、トリガーを使用する必要があります。

于 2012-09-26T19:25:03.223 に答える
1

わお!それは簡単でした!スキップしListBoxItemたい では、 に設定FocusableするだけFalseです。

やった!

于 2012-09-26T18:35:17.233 に答える