【问题标题】:Preventing almost duplicate RelayCommands in MVVM/MDI app防止 MVVM/MDI 应用程序中几乎重复的 RelayCommands
【发布时间】:2012-02-12 02:51:04
【问题描述】:

我正在使用 MDI 解决方案(请参阅 http://wpfmdi.codeplex.com/)和 MVVM。

我使用一个 RelayCommand 将工具栏和/或菜单绑定到主 ViewModel,例如:

 ICommand _editSelectedItemCommand;
    public ICommand EditSelectedItemCommand
    {
        get
        {
            return _editSelectedItemCommand ?? (_editSelectedItemCommand = new RelayCommand(param => CurrentChildViewModel.EditSelectedItem(),
                param => ((CurrentChildViewModel != null) && (CurrentChildViewModel.CanExecuteEditSelectedItem))));
        }
    }

但是,在子窗口中,要将按钮绑定到相同的功能,我需要另一个几乎相等的 RelayCommand,除了它直接调用方法 EditSelectedItem 和 CanExecuteEditSelectedItem。它看起来像:

 ICommand _editSelectedItemCommand;
    public ICommand EditSelectedItemCommand
    {
        get
        {
            return _editSelectedItemCommand ?? (_editSelectedItemCommand = new RelayCommand(param => EditSelectedItem(),
                param => CanExecuteEditSelectedItem))));
        }
    }

我需要大约 10 个,将来可能需要 50 个或更多这样的命令,所以我现在喜欢以正确的方式来做。 有没有办法防止这种情况或更好的方法来做到这一点?

【问题讨论】:

    标签: c# wpf mvvm mdi relaycommand


    【解决方案1】:

    您可以从主视图模型中删除第一个命令,因为子视图模型中的命令绰绰有余。

    只需在 xaml 标记中使用这样的绑定:

    <Button Command="{Binding CurrentChildViewModel.EditSelectedItemCommand}" 
            Content="Button for the main view model" />
    

    此外,如果我正确理解您的代码,则规定如果CurrentChildViewModel 属性为空,则该命令将被禁用。 如果您需要这样的行为,您应该将此转换器添加到您的代码中并稍微重写绑定:

    public class NullToBooleanConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return value != null;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    XAML:

    <Application.Resources>
        <local:NullToBooleanConverter x:Key="NullToBooleanConverter" />
    </Application.Resources>
    <!-- your control -->
    <Button Command="{Binding CurrentChildViewModel.EditSelectedItemCommand}" 
            IsEnabled="{Binding CurrentChildViewModel, Converter={StaticResource NullToBooleanConverter}}" />
    

    【讨论】:

    • 抱歉,检查它是否有效需要一些时间(我只是 WPF 的初学者,所以我花了一些时间来改变这里和那里的东西)。您的解决方案效果很好,我还学到了更多关于转换器的知识。感谢您花时间解决问题!
    • 我测试了它,它可以工作,谢谢。但是,对于几种方法,我需要更复杂的 IsEnabled 功能,我应该调用 IsEnabled={Binding CurrentChildViewModel.CanExecuteSelectedItem} 并在该函数中实现逻辑和/或在这种情况下是否需要转换器?提前致谢。
    • 我在stackoverflow.com/questions/9274498/… 添加了一个附加问题...我很新,所以我不知道这是否是“正常的工作方式”。
    • @Michel Keijzers WPF 中有 MultiBinding 类,它可以帮助您解决问题。绑定只适用于属性,不能绑定到方法。
    • 好的,我可以毫无问题地把它变成一个属性。
    猜你喜欢
    • 2010-12-05
    • 2018-10-08
    • 1970-01-01
    • 2012-02-06
    • 2014-04-25
    • 1970-01-01
    • 1970-01-01
    • 2013-07-04
    • 2011-06-03
    相关资源
    最近更新 更多