RelayCommand nicht Ausgeführt, Auf den Button Klicken
Ich Hänge schon länger an diesem problem für ein paar Stunden. Ich bin versucht zu implementieren, die eine MVVM-Stil Word-Add-In in WPF. Ich bin nicht mit einem MVVM toolkit. Ich habe eine WPF-Benutzer control angedockt ist innerhalb einer WinForm. Während ich in der Lage bin zu sehen, die WPF user control in der form gewinnen und mit ihm zu interagieren, meine generische RelayCommand gebunden ist, um ein WPF-button wird nicht ausgeführt, wenn ich auf die Schaltfläche klicke. Die RelayCommand Leben im ViewModel.cs und der DataContext der view wird über den code-behind. Ich bin sicher, ich Tue etwas albern, aber kann nicht herausfinden, was es ist und daher nicht sicher, warum RelayCommand property get{} wird nicht ausgeführt. Bitte sehen Sie sich den folgenden code ein. Vielen Dank im Voraus für die Hilfe!
RelayCommand.cs (code-snippet schließt namespace und enthält Aussagen)
///<summary>
///RelayCommand
///</summary>
///<typeparam name="T">Generic Parameter</typeparam>
public class RelayCommand<T> : ICommand where T : class
{
#region Constructors
///<summary>
///RelayCommand constructor
///</summary>
///<param name="exec">Delegate that encapsulates a method that takes in a single parameter and returns void</param>
///<param name="canExec">Delegate that encapsulates a method that defines a set of criteria and returns a true if criteria is met; else false</param>
public RelayCommand(Action<T> execute, Predicate<T> canExecute = null)
{
if (execute == null)
throw new ArgumentNullException("execute is null");
_canExecute = canExecute;
_execute = execute;
}
#endregion
#region Members
///<summary>
///Execute method
///</summary>
///<param name="param">Parameter</param>
public void Execute(object param)
{
T obj = param as T;
if(obj != null)
{
_execute(obj);
}
}
///<summary>
///CanExec is a method that shows whether or not execution can happen
///</summary>
///<param name="param">Parameter</param>
///<returns>true if can execute; else false</returns>
public bool CanExecute(object param)
{
if (_canExecute == null)
return true;
T obj = param as T;
return obj == null || _canExecute(obj);
}
///<summary>
///CanExec event changed
///</summary>
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
#endregion
#region Fields
private readonly Predicate<T> _canExecute;
private readonly Action<T> _execute;
#endregion
}
SubmissionUserControl.xaml (nur die relevanten Code-Ausschnitt gezeigt. schließt einige code)
<Button Grid.Column="2" x:Name="SubmitButton" Command="{Binding Path=SubmitCommentCommand}"
Content="Submit" HorizontalAlignment="Right" Margin="5"/>
SubmissionUserControl.xaml.cs (enthält snippet, wo ich mich auf die ViewModel)
ViewModel viewModel;
public SubmissionUserControl()
{
InitializeComponent();
viewModel = new ViewModel();
DataContext = viewModel;
}
ViewModel.cs (ohne code. zeigt nur die relevanten RelayCommand)
///<summary>
///SubmitCommentCommand responsible for interacting with UI to submit a comment.
///</summary>
///<returns>Returns a RelayCommand that executes a method to Save comments from the comment box</returns>
public ICommand SubmitCommentCommand
{
get
{
return _submitCommentCommand ?? (_submitCommentCommand = new RelayCommand<object>(param => this.SaveComment()));
}
}
- Nichts ist falsch in deinem code.. überprüfen Sie die Datacontext-richtig angewandt wird.. fügen Sie ein text-Eigenschaft gebunden und es auf einen textblock, und überprüfen Sie, dass zeigt?
- verwenden Sie Snoop (snoopwpf.codeplex.com), um zu überprüfen datacontext auf Laufzeit
- es scheint mir, dass Ihr nicht zu schicken, ein Befehl parameter , und in Ihrem RelayCommand Implementierung, die Sie aus irgendeinem Grund nur Anruf ausführen, wenn der parameter nicht null ist.
- Warum sind Sie mit ICommand statt RelayCommand in der ViewModel.cs?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Geben Sie einen detaillierteren Einstieg in MVVM und RelayCommands:
Haben Sie nicht zu erklären ViewModel in Xaml, dies geschieht meist programmgesteuert Anwendung auf root-Ebene, vielleicht mit einigen DI.
Beim Aufkleben dieser MSDN-Artikel Ihre RelayCommand sollte wie folgt Aussehen:
Zusätzlich definieren Sie eine generische RelayCommand zu handhaben Commandparameters wie diese:
In der ViewModel die RelayCommands sollte definiert werden, wie diese (ich INotifyPropertyChanged implementiert sowie für weitere WPF-Xaml-Eigenschaft Umgang mit Beispiel):
Ich Ihre Button-Beispiel in ein frisches WPF-Anwendung wie diese:
Und legen Sie die DataContext-wie dies der Einfachheit halber (Wie gesagt, dies geschieht in der Regel durch eine Art von DI auf der root-Ebene):
Dann sollte alles gut funktionieren.
Ich löste dieses Problem, indem er dem Modell über die Daten-Rahmen in xaml statt .cs-Datei.
Erste: Erzählen-Modell der namespace, in dem Sie platziert Ihre view-Modell, bei mir war wie folgt:
xmlns:Local="clr-namespace:MKPL.Views.A01.S020"
Zweite: Fügen Sie Ihre ViewModel in der xaml-Ressourcen wie:
UserControl.Resources
Local:ViewModel x:Key="dvm"
UserControl.Resources
Dritte: Hinzufügen DataContext auf den Übergeordneten container,in meinem Fall ist das ist Grid.
Grid x:Name="LayoutRoot" DataContext="{Binding Source={StaticResource dvm}}"
Viertens: In Ihrem button-code hinzufügen, werden die Daten Kontext:
Button Grid.Column="2" x:Name="SubmitButton" Command="{Binding Path=SubmitCommentCommand, Source={StaticResource dvm}}"
Content="Submit" HorizontalAlignment="Right" Margin="5"
Hoffe, es wird Ihnen helfen,