0

我正在使用带有 Prism 的 MVVM 模式

我的模型中有一个 ObservableCollection 中的元素列表。在我的视图中,我将 ObservableCollection 绑定到 Listview,然后尝试显示 1 个绑定到名为 DoSomethingCommand 的 DelegateCommand 的按钮。这意味着我的 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

对于您的问题,我有两个解决方案:

第一个解决方案:

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

这里有所有示例代码 (ListViewDelegateCommand.zip)。

于 2012-11-05T21:17:30.177 回答