Diese Frage zu meiner vorherigen Frage hier bezogen werden: Predicate won't validate parameter correctlyDatacontext auf Command unterscheidet sich von Datacontext auf Befehl selbst
Zuerst einige Informationen über meine Models:
BaseViewModel:
public abstract class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _name;
public string Name
{
get
{
return _name;
}
set
{
if (Name != value)
{
_name = value;
OnPropertyChanged("Name");
}
}
}
private BaseViewModel _homePage;
public BaseViewModel HomePage
{
get
{
return _homePage;
}
set
{
if (HomePage != value)
{
_homePage = value;
OnPropertyChanged("HomePage");
}
}
}
public void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler temp = PropertyChanged;
if (temp != null)
{
temp(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Problem:
Wie Sie in der BaseViewModel sehen können Die Eigenschaften "Name" und "HomePage" sind in derselben Klasse definiert, sodass sie zugänglich sein sollten, wenn der DataContext ein ViewModel ist, das von "BaseViewModel" abgeleitet ist. Zuerst verlor ich meine Meinung, weil nichts zu funktionieren schien - das Ausgabefenster sagte, dass der Wert von "HomePage" nicht abgerufen werden konnte - anderer als der Name, der jedes Mal richtig gebunden wurde.
Nachdem ich gab fast ich meine Ansicht „Test“ genannt und versuchte, die Command Bindung entlang eines Elements zu umleiten - und es funktioniert:
<Button Content="{Binding Name}" Command="{Binding DataContext.ChangePageCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
CommandParameter="{Binding DataContext.HomePage, ElementName=Test}"/>
Aber warum? Warum unterscheidet sich der DataContext zwischen der Name-Eigenschaft, die gebunden werden kann, ohne ein ElementName zuzuweisen, und HomePage, für die ElementName erforderlich ist?
Update 1:
MainViewModel: BaseViewModel
private RelayCommand _command;
public RelayCommand ChangePageCommand {
get {
return _command ?? (_command = new RelayCommand(p => ChangeViewModel((BaseViewModel)p), x => {
return x is BaseViewModel;
}));
}
}
public void ChangeViewModel(BaseViewModel viewModel) {
CurrentPageViewModel = viewModel;
}
Update 2:
<Window.Resources>
<DataTemplate DataType="{x:Type home:HomeViewModel}">
<home:Home/>
</DataTemplate>
<DataTemplate DataType="{x:Type ua:UserAdministrationViewModel}">
<ua:UserAdministration/>
</DataTemplate>
</Window.Resources>
<ContentControl Content="{Binding CurrentPageViewModel}"/>
Update 3:
Jetzt wird es wirklich seltsam - ich habe versucht, einen TextBlock hinzuzufügen und direkt an HomePage.Text zu binden - und es funktioniert.
<Button Height="50" Content="{Binding Name}" Command="{Binding DataContext.ChangePageCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
CommandParameter="{Binding DataContext.HomePage, ElementName=Test}"/>
<TextBlock Text="{Binding HomePage.Name}"/>
Warum also nicht direkt HomePage greife ich auf, wenn an der Command Bindung sondern eine TextBlock- Eigenschaft Text Bindung direkt an HomePage.Name funktioniert?
Update 4:
Die Ausgabe von Windows sais:
System.Windows.Data Informationen: 10: Kann nicht abrufen Wert der Bindung und keine gültige Fehlerwert existiert verwendet wird; Verwenden Sie stattdessen die Standardeinstellung. BindingExpression: Pfad = Name; Datenelement = null; Zielelement ist 'Button' (Name = ''); Zieleigenschaft ist 'Inhalt' (Typ 'Objekt')
System.Windows.Data Information: 10: Kann Wert nicht abrufen, der die Bindung verwendet und kein gültiger Fallbackwert existiert; Verwenden Sie stattdessen die Standardeinstellung. BindingExpression: Pfad = DataContext.ChangePageCommand; Datenelement = null; Ziel Element ist 'Button' (Name = ''); Zieleigenschaft ist 'Befehl' (Typ 'ICommand')
System.Windows.Dateninformation: 10: Wert kann nicht mithilfe der Bindung abgerufen werden, und es ist kein gültiger Ersatzwert vorhanden; Verwenden Sie stattdessen die Standardeinstellung. BindingExpression: Pfad = HomePage; Datenelement = null; Zielelement ist 'Button' (Name = ''); Zieleigenschaft ist 'CommandParameter' (Typ 'Objekt')
System.Windows.Data Information: 10: kann Wert nicht abrufen, der die Bindung verwendet, und kein gültiger Fallbackwert existiert; Verwenden Sie stattdessen die Standardeinstellung. BindingExpression: Pfad = HomePage.Name; Datenelement = null; Zielelement ist 'TextBlock' (Name = ''); target -Eigenschaft ist 'Text' (Typ 'String')
Aber alles außer dem CommandParameter wird erfolgreich gebunden. Ist es möglich, dass der CommandParameter (und die darunter liegende CanExecute-Methode) nicht erneut überprüft werden, sobald die Bindung aktualisiert wird? Möglicherweise schlägt die Bindung zuerst fehl, aber jede Bindung außer dem CommandParameter wird aktualisiert und erneut validiert. Aber wie könnte ich dieses Problem lösen?
Können Sie den Code anzeigen, wo sich ChangePageCommand befindet ?, –
. Sehen Sie sich die aktualisierte Quest an. – C4p741nZ
Und wo Sie den DataContext dieser Ansicht setzen, –