子窗口中的命令绑定

问题描述:

命令是使用中继命令实现的。我已经在它自己的类所做的这一点,如下图所示:子窗口中的命令绑定

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

在主窗口我下面的设置数据上下文。 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"); 
     } 
    } 

的主窗口视图模型看起来类似,它只有不同的命令。现在从settingsWindow我做一个按钮,如下:

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

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

+0

请显示设置'DataContext'的位置。 – Fruchtzwerg

+0

请输入密码。这里没有任何人可以调试或诊断。例如,这个句子包含的信息非常少,几乎让我觉得我知道的知识少于阅读之前的知识:*“出于某种原因,它似乎仍锁定在mainWindowViewModel”*。 “锁定”? “似乎”?你在说什么?请向我们展示a)设置viewmodel中命令属性的代码; b)设置窗口中的命令绑定XAML; c)您如何将设置窗口中的DataContext设置为viewmodel设置。 –

+0

对不起,在第一篇文章缺乏信息。我现在已经更新了它,希望前面的问题更有意义。 – Aune

该代码看起来不错。

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

无论如何,你分配了一个新的数据上下文到SettingsWindow,所以对于这个窗口数据上下文是SettingsWindowViewModel,那里应该按预期工作。  

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

“Still?”一个窗口不会检测另一个窗口的DataContext,因此您必须在代码的某处将SettingsWindowDataContext设置为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添加到SettingsWindow.xaml