当Listview的项目发生更改时,触发RaiseCanExecuteChanged

时间:2012-11-05 18:29:38

标签: wpf listview mvvm command

我使用带有Prism的MVVM模式

我的模型中的ObservableCollection中有一个元素列表。在我的视图中,我将ObservableCollection绑定到Listview,然后我尝试显示绑定到名为DoSomethingCommand的DelegateCommand的1个按钮。这意味着我的Listview的每一行都有一个按钮来调用DoSomethingCommand,CommandParameter绑定到元素的ID。

约束:DoSomethingCommand会将元素的状态字段更改为" done"。当一个元素完成时#34;我想按钮调用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);

2 个答案:

答案 0 :(得分:1)

如果你正在使用Prism的EventAggregator,并且我认为你是因为你正在使用Prism,那么你可以订阅一个事件并在你的DelegateCommand上调用RaiseCanExecuteChanged()。

这样的事情:

_eventAggregator.GetEvent<YourCompositePresentationEvent>().Subscribe((i) => { YourDelegateCommand.RaiseCanExecuteChanged(); });

答案 1 :(得分:0)

我有两个问题的解决方案:

第一个解决方案:

如果您在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;
    }

第二个解决方案:

您可以在不调用RaiseCanExecuteChanged方法的情况下执行此操作。

 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;
    }

Here您拥有所有示例代码(ListViewDelegateCommand.zip)。