0

PrismでMVVMパターンを使用しています

モデルの ObservableCollection に要素のリストがあります。私のビューでは、ObservableCollection を Listview にバインドしてから、DoSomethingCommand という DelegateCommand にバインドされた 1 つのボタンを表示しようとしました。これは、Listview の各行に DoSomethingCommand を呼び出すボタンがあり、CommandParameter が要素の ID にバインドされていることを意味します。

制約: DoSomethingCommand は、要素のステータス フィールドを「完了」に変更します。要素が「完了」したら、DoSomethingCommand を呼び出すボタンを無効にする必要があります。

論理的には、コマンドを実装するときに canExecuteDoSomethingCommand デリゲートを用意するだけです。しかし、問題は、いつ、どのように DoSomethingCommand.RaiseCanExecuteChanged を発生させることができるかということです。BTW Element は、変更できないサード パーティの dll の一部ですが、既に INotifyPropertyChanged を実装しています。

<ListView BorderThickness="0" Width="Auto"
              ItemsSource="{Binding ElementList}"
              >
   <ListView.View>
     <GridView>
       <GridViewColumn Header="Actions">
         <GridViewColumn.CellTemplate>
             <DataTemplate>
                <StackPanel Orientation="Horizontal">
                     <Button Command="{Binding DataContext.DoSomethingCommand, RelativeSource={RelativeSource AncestorType={x:Type ListView}}}" CommandParameter="{Binding ID}" >Accept</Button>
                </StackPanel>
             </DataTemplate>
           </GridViewColumn.CellTemplate>
        </GridViewColumn>

コマンドの実装

DoSomethingCommand = new DelegateCommand<string>(executeDoSomethingCommand, canExecuteDoSomethingCommand);
4

2 に答える 2

1

Prism の EventAggregator を使用している場合は、Prism を使用しているためだと思いますが、イベントにサブスクライブして、DelegateCommand で RaiseCanExecuteChanged() を呼び出すことができます。

このようなもの:

_eventAggregator.GetEvent<YourCompositePresentationEvent>().Subscribe((i) => { YourDelegateCommand.RaiseCanExecuteChanged(); });
于 2012-11-05T20:14:38.180 に答える
0

私はあなたの問題に対して2つの解決策を持っています:

最初の解決策:

クラスINotifyPropertyChangedに実装すれば、それは素晴らしいことです。Elementたぶん、あなたは別のクラスを作成し、それらの間で変換することができますか?コードは次のようになります。

 public ICommand DoSomethingCommand { get; private set; }
    private void OnDoSomethingCommand(object param)
    {
        Element tmp = param as Element;

        if (tmp != null)
        {
            tmp.Status = "done";
        }                

        (DoSomethingCommand as DelegateCommand<object>).RaiseCanExecuteChanged();
    }

    private bool CanDoSomethingCommand(object param)
    {
        Element tmp = param as Element;

        if (tmp != null)
        {
            if (tmp.Status != null && tmp.Status.Equals("done"))
                return false;
            else
                return true; 
        }
        return true;
    }

2番目の解決策:

RaiseCanExecuteChangedこれは、invokeメソッドなしで実行できます。

 public ICommand DoSomethingCommand { get; private set; }
    private void OnDoSomethingCommand(object param)
    {
        Element tmp = param as Element;

        if (tmp != null)
        {
            tmp.Status = "done";
        }

        List<Element> refresh = new List<Element>(ElementList);
        ElementList.Clear();
        foreach (var item in refresh)
        {
            ElementList.Add(item);
        }          
    }

    private bool CanDoSomethingCommand(object param)
    {
        Element tmp = param as Element;

        if (tmp != null)
        {
            if (tmp.Status != null && tmp.Status.Equals("done"))
                return false;
            else
                return true; 
        }
        return true;
    }

ここにすべてのサンプルコード(ListViewDelegateCommand.zip)があります。

于 2012-11-05T21:17:30.177 に答える