web-dev-qa-db-ja.com

ViewModelBaseのコマンドにWPFボタンをバインドする方法は?

あらゆる種類の属性を含むビューAttributeViewがあります。ボタンを押すと、属性にデフォルト値を設定する必要があります。また、所有するすべてのViewModelの基本クラスであるViewModelBaseクラスもあります。問題は、WPFでコマンドにバインドされたボタンを取得できないように見えることです。

私はこれを試しましたが、何もしません:

<Button Command="{Binding DataInitialization}" Content="{x:Static localProperties:Resources.BtnReinitializeData}"></Button>

コマンドは次のように定義されます(ViewModelBaseで):

public CommandBase DataInitialization { get; protected set; }

アプリケーションの起動時に、コマンドの新しいインスタンスが作成されます。

DataInitialization = new DataInitializationCommand()

ただし、WPFバインディングはコマンドを「見つけた」ようには見えません(ボタンを押しても何も起こりません)。現在のビューで使用されているViewModelは、ViewModelBaseから派生しています。他に何を試すことができますか(私はWPFにまったく慣れていないので、これは非常に簡単な質問かもしれません)?

44
kor_
 <Grid >
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Button Command="{Binding ClickCommand}" Width="100" Height="100" Content="wefwfwef"/>
</Grid>

ウィンドウのコードビハインド:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new ViewModelBase();
    }
}

ViewModel:

public class ViewModelBase
{
    private ICommand _clickCommand;
    public ICommand ClickCommand
    {
        get
        {
            return _clickCommand ?? (_clickCommand = new CommandHandler(() => MyAction(), ()=> CanExecute));
        }
    }
     public bool CanExecute
     {
        get
        {
            // check if executing is allowed, i.e., validate, check if a process is running, etc. 
            return true/false;
        }
     }

    public void MyAction()
    {

    }
}

コマンドハンドラー:

 public class CommandHandler : ICommand
{
    private Action _action;
    private Func<bool> _canExecute;

    /// <summary>
    /// Creates instance of the command handler
    /// </summary>
    /// <param name="action">Action to be executed by the command</param>
    /// <param name="canExecute">A bolean property to containing current permissions to execute the command</param>
    public CommandHandler(Action action, Func<bool> canExecute)
    {
        _action = action;
        _canExecute = canExecute;
    }

    /// <summary>
    /// Wires CanExecuteChanged event 
    /// </summary>
    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    /// <summary>
    /// Forcess checking if execute is allowed
    /// </summary>
    /// <param name="parameter"></param>
    /// <returns></returns>
    public bool CanExecute(object parameter)
    {
        return _canExecute.Invoke();
    }

    public void Execute(object parameter)
    {
        _action();
    }
}

これがあなたにアイデアを与えることを願っています。

109
yo chauhan

ここで倫理学が提案する解決策は魅力のように機能します。ただ1つの発言-独自のCommandHandlerを実装する代わりに、Microsoft.Practices.Prism.Commands.DelegateCommandを使用することを検討してください(ボタンが常に有効な場合の追加のctorを除き、実質的に同じです)。

0
erezmk