次の方法で共有


コマンドの一覧を更新する

へ: コマンドの追加

ここまでは、拡張機能内の静的項目の一覧を返す方法を示しました。 ただし、項目を変更したり、リアルタイム データを表示したり、システムの状態を反映したりすることもできます。 この記事では、拡張機能のコマンドの一覧を更新する方法について説明します。

コマンドの更新

コマンド パレットのほぼすべての拡張オブジェクトは 、IPropChanged インターフェイスを実装します。 これにより、変更されたときにコマンド パレットに通知でき、コマンド パレットによって UI が更新され、それらの変更が反映されます。 ツールキットの実装を使用している場合、このインターフェイスは、それをサポートするプロパティ用に既に実装されています。

簡単な例として、ページのタイトルを更新できます。 これを行うには、ページのタイトルを更新するコマンドを追加できます。

public override IListItem[] GetItems()
{
    OpenUrlCommand command = new("https://learn.microsoft.com/windows/powertoys/command-palette/creating-an-extension");

    AnonymousCommand updateCommand = new(action: () => { Title += " Hello"; }) { Result = CommandResult.KeepOpen() };

    return [
        new ListItem(command)
        {
            Title = "Open the Command Palette documentation",
        },
        new ListItem(updateCommand),
    ];
}

ここでは、 AnonymousCommand を使用して、ページのタイトルを更新するコマンドを作成します。 AnonymousCommand は、再利用する必要のないシンプルで軽量なコマンドを作成するのに役立つヘルパーです。

もちろん、カスタム ListItem オブジェクトも作成できます。

internal sealed partial class IncrementingListItem : ListItem
{
    public IncrementingListItem() :
        base(new NoOpCommand())
    {
        Command = new AnonymousCommand(action: Increment) { Result = CommandResult.KeepOpen() };
        Title = "Increment";
    }

    private void Increment()
    {
        Subtitle = $"Count = {++_count}";
    }

    private int _count;
}
    public override IListItem[] GetItems()
    {
        OpenUrlCommand command = new("https://learn.microsoft.com/windows/powertoys/command-palette/creating-an-extension");
        return [
            new ListItem(command)
            {
                Title = "Open the Command Palette documentation",
            },
            new ListItem(new ShowMessageCommand()),
+            new IncrementingListItem(),
        ];
    }

あなたは、コマンドパレット拡張機能として、独自のアイドル クリッカー ゲームを作成する途中です。

コマンドの一覧の更新

ページ上の項目の一覧を変更することもできます。 これは、結果を非同期に読み込むページや、アプリの状態に基づいて異なるコマンドを表示するページに役立ちます。

これを行うには、ListPage オブジェクトで RaiseItemsChanged メソッドを使用できます。 これにより、項目のリストが変更されたことがコマンド パレットに通知され、項目のリストが再フェッチされます。 例として、上の IncrementingListItem でページ上の項目の一覧を更新してみましょう。

ページへの参照を取得するようにリスト アイテムを更新し、カウントをインクリメントするメソッドを追加します。

internal sealed partial class IncrementingListItem : ListItem
{
    public IncrementingListItem(<ExtensionName>Page page) :
        base(new NoOpCommand())
    {
        _page = page;
        Command = new AnonymousCommand(action: _page.Increment) { Result = CommandResult.KeepOpen() };
        Title = "Increment";
    }

    private <ExtensionName>Page _page;
}

次に、次のようにページを変更します。

public <ExtensionName>Page()
{
    Icon = IconHelpers.FromRelativePath("Assets\\StoreLogo.png");
    Title = "My sample extension";
    Name = "Open";

    _items = [new IncrementingListItem(this) { Subtitle = $"Item 0" }]; 
}
public override IListItem[] GetItems()
{
    return _items.ToArray();
}
internal void Increment()
{
    _items.Add(new IncrementingListItem(this) { Subtitle = $"Item {_items.Count}" });
    RaiseItemsChanged();
}
private List<ListItem> _items;

これで、 IncrementingListItem コマンドのいずれかを実行するたびに、ページ上の項目の一覧が更新され、別の項目が追加されます。 ページが所有する 1 つの リスト を使用して、すべてのアイテムを所有しています。 特に、RaiseItemsChanged を呼び出す前に、Increment メソッドに新しい項目を作成しています。 IInvokableCommand呼び出しには、必要な時間がかかることがあります。 すべてのコードはコマンド パレットとは別のプロセスで実行されるため、UI はブロックされません。 ただし、 RaiseItemsChanged を呼び出す前に項目を構築すると 、拡張機能の 応答性が向上します。

読み込みスピナーの表示

これまでのすべてが瞬時に完了しました。 ただし、多くの拡張機能では、時間がかかる作業が必要になる場合があります。 その場合は、 Page.IsLoading をtrue に設定して、読み込みスピナーを表示できます。 これは、拡張機能がバックグラウンドで何かを行っていることを示すのに役立ちます。

前のセクションから作業している場合は、以下のコードを Page.IsLoading から this.IsLoadingに変更します。

internal void Increment()
{
    Page.IsLoading = true;
    Task.Run(() =>
    {
        Thread.Sleep(5000);
        _items.Add(new IncrementingListItem(this) { Subtitle = $"Item {_items.Count}" });
        RaiseItemsChanged();
        Page.IsLoading = false;
    });
}

作業を開始する前に 、IsLoading をtrue に設定することをお勧めします。 次に、すべての作業を行って、ユーザーに表示する必要があるすべての新しい ListItem を ビルドします。 次に、項目の準備ができたら、 RaiseItemsChanged を呼び出し、 IsLoading をfalse に戻します。 これにより、読み込みスピナーが作業全体の間表示され、作業が完了するとすぐに UI が更新されます (拡張機能が新しい ListItem オブジェクトを構築するのを待つ必要はありません)。

次へ: 拡張機能に最上位のコマンドを追加する