子窗口中的命令绑定

时间:2017-09-14 18:29:40

标签: c# wpf binding

使用中继命令实现命令。我已经在它自己的课程中完成了这个,如下所示:

namespace Log_Reader.commands
{
    using System;
    using System.Windows.Input;

    public class RelayCommand : ICommand
    {
        readonly Action<object> _execute;
        readonly Predicate<object> _canExecute;

        public RelayCommand(Action<object> execute, Predicate<object> canExecute)
        {
            if (execute == null)
                throw new NullReferenceException("execute");

            _execute = execute;
            _canExecute = canExecute;
        }

        public RelayCommand(Action<object> execute) : this(execute, null)
        {

        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public bool CanExecute(object parameter)
        {
            return _canExecute == null ? true : _canExecute(parameter);
        }

        public void Execute(object parameter)
        {
            _execute.Invoke(parameter);
        }
    }
}

在mainWindow中,我执行以下操作来设置数据上下文。 buttonclick处理程序打开第二个窗口。

public partial class MainWindow : Window
    {
        LogEntriesViewModel viewModel = new LogEntriesViewModel();

        public MainWindow()
        {
            InitializeComponent();
            DataContext = viewModel;

        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            SettingsWindow settings = new SettingsWindow();
            settings.WindowStartupLocation = WindowStartupLocation.CenterOwner;
            settings.ShowDialog();
        }
    }

对于第二个窗口,在构造函数中我设置了datacontext。

public SettingsWindow()
        {
            InitializeComponent();
            DataContext = new SettingsWindowViewModel();
        }

settingsWindowViewModel如下所示:

using Log_Reader.commands;
    using System.Windows;

    public class SettingsWindowViewModel
    {
        public RelayCommand SaveCommand { get; private set; }
        public RelayCommand CancelCommand { get; private set; }

        public SettingsWindowViewModel()
        {
            /* Creating commands */
            SaveCommand = new RelayCommand(SaveChanges, null);
            CancelCommand = new RelayCommand(CancelChanges, null);
        }

        public void SaveChanges(object obj)
        {
            MessageBox.Show("Save stuff");
        }

        public void CancelChanges(object obj)
        {
            MessageBox.Show("Cancel stuff");
        }
    }

mainWindow的viewmodel看起来很相似,它只有不同的命令。现在从settingsWindow我在按钮上执行以下操作:

<Button Content="Save" Command="{Binding SaveCommand}" />

现在,当我按下此按钮时,没有任何反应,我在输出窗口中收到错误,它在settingsWindowViewModel中找不到SaveCommand。但是如果我用mainWindowViewModel中定义的命令替换button命令,它会正确触发。这就是为什么看起来像datacontext仍然是mainWindowViewModel。

2 个答案:

答案 0 :(得分:0)

代码看起来很好。

我在这里没有看到任何错误。我认为如果你执行这个代码它应该工作。

无论如何,您为SettingsWindow分配了一个新的数据上下文,因此对于此窗口,数据上下文为SettingsWindowViewModel,并且它应该按预期工作。

答案 1 :(得分:0)

  

这就是为什么看起来像datacontext仍然是mainWindowViewModel。

“仍然?”窗口不会覆盖另一个窗口的DataContext,因此您必须在代码中的某处将DataContext的{​​{1}}设置为SettingsWindow。或者LogEntriesViewModel位于Button

尝试像这样设置子窗口的MainWindow

DataContext

...并确保将private void Button_Click(object sender, RoutedEventArgs e) { SettingsWindow settings = new SettingsWindow(); settings.WindowStartupLocation = WindowStartupLocation.CenterOwner; settings.DataContext = new SettingsWindowViewModel(); settings.ShowDialog(); } 添加到Button