5

OK、XAML は非常にシンプルで、MVVM を使用ICommand SomeCommand { get; }してビュー モデルのプロパティにバインドします。

<Button Command="{Binding Path=SomeCommand}">Something</Button>

SomeCommandが返された場合null、ボタンは有効になっています。(そのメソッドを呼び出すインスタンスがないため、CanExecute(object param)メソッド onとは関係ありません)ICommand

そして今、質問: ボタンが有効になっているのはなぜですか? どのように回避しますか?

「有効」ボタンを押すと、明らかに何も呼び出されません。ボタンが有効に見えるのは醜いです。

4

3 に答える 3

7

私の同僚は、バインディング フォールバック値を使用するというエレガントな解決策を見つけました。

public class NullCommand : ICommand
{
    private static readonly Lazy<NullCommand> _instance = new Lazy<NullCommand>(() => new NullCommand());

    private NullCommand()
    {
    }

    public event EventHandler CanExecuteChanged;

    public static ICommand Instance
    {
        get { return _instance.Value; }
    }

    public void Execute(object parameter)
    {
        throw new InvalidOperationException("NullCommand cannot be executed");
    }

    public bool CanExecute(object parameter)
    {
        return false;
    }
}

XAML は次のようになります。

<Button Command="{Binding Path=SomeCommand, FallbackValue={x:Static local:NullCommand.Instance}}">Something</Button>

このソリューションの利点は、デメテルの法則を破り、各インスタンスが になる可能性のある結合パスにいくつかのドットがある場合に、よりうまく機能することですnull

于 2013-08-27T12:10:06.520 に答える
5

ジョンの答えと非常によく似ていますが、コマンドセットがないときに無効にする必要があるボタンをマークするトリガー付きのスタイルを使用できます。

<Style x:Key="CommandButtonStyle"
        TargetType="Button">
    <Style.Triggers>
        <Trigger Property="Command"
                    Value="{x:Null}">
            <Setter Property="IsEnabled"
                    Value="False" />
        </Trigger>
    </Style.Triggers>
</Style>

問題に非常に直接的に対処し、新しい型を必要としないため、私はこの解決策を好みます。

于 2014-06-18T13:19:11.130 に答える
5

これがデフォルトの状態であるため、有効になっています。自動的に無効にすることは、他の問題を引き起こす恣意的な手段です。

コマンドが関連付けられていないボタンを無効にしたい場合は、適切なコンバーターを使用してIsEnabledプロパティをバインドします。SomeCommand

[ValueConversion(typeof(object), typeof(bool))]
public class NullToBooleanConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value !== null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}
于 2013-08-26T15:41:59.897 に答える