2017-09-14 83 views
0

命令是使用中繼命令實現的。我已經在它自己的類所做的這一點,如下圖所示:子窗口中的命令綁定

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

回答

0

該代碼看起來不錯。

我在這裏沒有看到任何錯誤。我想如果你執行這個代碼它應該工作。

無論如何,你分配了一個新的數據上下文到SettingsWindow,所以對於這個窗口數據上下文是SettingsWindowViewModel,那裏應該按預期工作。  

0

這就是爲什麼它看起來像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