2016-08-15 102 views
0

下面是一個非常簡單的Prism.Wpf示例,其中DelegateCommand包含ExecuteCanExecute兩個代表。棱鏡:必須顯式調用RaiseCanExecuteChanged()

假設CanExecute取決於某些屬性。似乎棱鏡的DelegateCommand不會在此屬性更改時自動重新評估CanExecute條件,因爲RelayCommand在其他MVVM框架中也會這樣做。相反,您必須在屬性設置器中顯式調用RaiseCanExecuteChanged()。這在任何非平凡的視圖模型中都會導致大量的重複代碼。

有沒有更好的方法?

視圖模型

using System; 
using Prism.Commands; 
using Prism.Mvvm; 

namespace PrismCanExecute.ViewModels 
{ 
public class MainWindowViewModel : BindableBase 
{ 
    private string _title = "Prism Unity Application"; 
    public string Title 
    { 
     get { return _title; } 
     set { SetProperty(ref _title, value); } 
    } 
    private string _name; 
    public string Name 
    { 
     get { return _name; } 
     set 
     { 
      SetProperty(ref _name, value); 

      // Prism doesn't track CanExecute condition changes? 
      // Have to call it explicitly to re-evaluate CanSubmit() 
      // Is there a better way? 
      SubmitCommand.RaiseCanExecuteChanged(); 
     } 
    } 
    public MainWindowViewModel() 
    { 
     SubmitCommand = new DelegateCommand(Submit, CanSubmit); 
    } 

    public DelegateCommand SubmitCommand { get; private set; } 
    private bool CanSubmit() 
    { 
     return (!String.IsNullOrEmpty(Name)); 
    } 
    private void Submit() 
    { 
     System.Windows.MessageBox.Show(Name); 
    } 

} 
} 

查看

<Window x:Class="PrismCanExecute.Views.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:prism="http://prismlibrary.com/" 
    Title="{Binding Title}" 
    Width="525" 
    Height="350" 
    prism:ViewModelLocator.AutoWireViewModel="True"> 
<Grid> 
    <!--<ContentControl prism:RegionManager.RegionName="ContentRegion" />--> 
    <StackPanel> 
     <StackPanel Orientation="Horizontal"> 
      <TextBlock Text="Name: " /> 
      <TextBox Width="150" 
        Margin="5" 
        Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}"/> 
     </StackPanel> 
     <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> 
      <Button Width="50" 
        Command="{Binding SubmitCommand}" 
        Content="Submit" Margin="10"/> 
      <!--<Button Width="50" 
        Content="Cancel" 
        IsCancel="True" Margin="10"/>--> 
     </StackPanel> 
    </StackPanel> 
</Grid> 
</Window> 

回答

4

正如@ l33t解釋的那樣,這是通過設計。如果您希望DelegateCommand自動監視VM屬性以進行更改,只需使用DelegateCommand的ObservesProperty方法即可:

var command = new DelegateCommand(Execute).ObservesProperty(()=> Name); 
1

這是由設計。它與性能相關。

雖然,您可以用自定義的命令替換棱鏡DelegateCommand做你想做的。例如。 this實現似乎是伎倆。但是,我不會推薦使用它。如果您有很多命令,您很可能會遇到性能問題。另請參閱answer

+0

謝謝。我還發現以下鏈接相當有用:(http://stackoverflow.com/questions/33459183/how-to-make-the-canexecute-trigger-properly-using-prism-6?rq=1)和相關的(http ://stackoverflow.com/questions/33313190/observesproperty-method-isnt-observing-models-properties-at-prism-6) – mechanic