web-dev-qa-db-ja.com

ToolbarItem Xamarin.Formsを無効にする

私のページには以下があります:

<ContentPage.ToolbarItems>
    <ToolbarItem Text="Run" Command="{Binding RunCommand}" />
</ContentPage.ToolbarItems>

コマンドは非同期タスクを開始します。次のようにブールプロパティにバインドして、非同期タスクが実行されている限り、コントロールを無効にしようとしています。

<ContentPage.ToolbarItems>
    <ToolbarItem Text="Run" Command="{Binding RunCommand}" IsEnabled="{Binding MyBoolProperty}" />
</ContentPage.ToolbarItems>

私の問題は、ToolbarItemの「IsEnabled」プロパティがないように見えることです。 Xamarin.Formsを使用して実行しようとしていることを達成する方法はありますか?

18
LostBalloon

ウィリアムとXamarinのサポートを受けて、ようやく機能の仕組みを見つけることができました。

ボタン(ToolbarItem)を有効/無効にすることを想定しているため、これは少し直観的ですが、実際には、ボタンにバインドされているコマンドの状態を管理する必要があります。このパターンを理解したら、それは理にかなっています。

ICommand型のCommandオブジェクトにはCanExecuteプロパティがあります(Williamに指摘していただきありがとうございます)コマンドを実行できるかどうかを実際に確認するためでない限り、直接アクセス/使用したくありません。

コードのどこにでも当てはまる場合は、コマンドの状態を変更するには、次の行を追加する必要があります。

((Command)_myCommand).ChangeCanExecute();

この行により、指定したコマンドのCanExecuteプロパティが強制的に再評価されます。

私は自分のアプリケーションで意味のあるように非アクティブを追跡する場所に追加することにしました。

public bool Inactive { 
    get { 
        return _inactive;
    } 
    set {
        if (_inactive != value) {
            _inactive = value;
            ((Command)_myCommand).ChangeCanExecute();
            OnPropertyChanged ();
        }
    }
}

ビューでは、注目すべき変更はありません。

<ToolbarItem Text="Run" Command="{Binding MyCommand}" />

Commandオブジェクトを作成すると、大きな作業が行われます。通常はそれで十分であり、コマンドが何をするかを定義するために、通常は単一引数コンストラクターを使用します。興味深いことに、CanExecuteプロパティの値を決定する関数/アクションを提供できる2つのパラメーターコンストラクターもあります。

_myCommand = new Command (async () => {
                                          Inactive = false;
                                          await Run();
                                          Inactive = true;
                                      },
                                      () => {
                                          return Inactive;
                                      });


public ICommand MyCommand {
    get { 
        return _myCommand;
    }
}

編集:Inactiveの値を技術的に変更することはRun()で行う必要があることを知っていますが、デモの目的で...

19
LostBalloon

この例は、削除ではなく無効にするためのものですが、便利な場合もあります。

    ToolbarItem delToolbar;       

    ...

        delToolbar = new ToolbarItem
        {
            Order = ToolbarItemOrder.Primary,                
            Text = "delete",              
            Command = new Command(async () =>
            {                                       
                ToolbarItems.Remove(delToolbar);
            })
        };
        ToolbarItems.Add(delToolbar);
2

これらの状況で私が学んだことは次のとおりです。

public Command RunCommand 
{ 
    get { return new Command(async() => await OnRunCommand()); }
}    

private bool _isRunning;

public async Task OnRunCommand() 
{
    if (_isRunning) return;
    _isRunning = true;

    // do stuff

    _isRunning = false;
}

downside:これにより、ツールバー項目は通常の状態のままになり、ユーザーは引き続きタップすることができます。

pside:これは、OnRunCommandタスクの同時実行を許可しないため、優れています。

無効な画像を表示してボタンを無効にする場合は、レンダラーを作成する必要があります。

タスクの実行中にツールバー項目を表示したくない場合は、ページからツールバー項目を削除して、後で再度追加することを検討してください。

1
Will Decker