Ich habe ein Problem beim Binden eines Befehls in einem Kontextmenü auf einem Benutzersteuerelement, das sich auf einer Registerkarte befindet. Das erste Mal, wenn ich das Menü benutze (rechte Maustaste auf die Registerkarte), funktioniert es großartig, aber wenn ich die Registerkarte wechsle, verwendet der Befehl die datenbankspezifische Instanz, die beim ersten Mal verwendet wurde.WPF-Kontextmenü bindet nicht an rechtes datengebundenes Element
Stecke ich eine Schaltfläche, die auf den Befehl in dem Usercontrol gebunden ist es wie erwartet funktioniert ...
Kann jemand bitte sagen Sie mir, was ich falsch mache ??
Dies ist ein Testprojekt, das das Problem aussetzt:
App.xaml.cs:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
CompanyViewModel model = new CompanyViewModel();
Window1 window = new Window1();
window.DataContext = model;
window.Show();
}
}
Window1.xaml:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vw="clr-namespace:WpfApplication1"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<DataTemplate x:Key="HeaderTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type vw:PersonViewModel}">
<vw:UserControl1/>
</DataTemplate>
</Window.Resources>
<Grid>
<TabControl ItemsSource="{Binding Path=Persons}"
ItemTemplate="{StaticResource HeaderTemplate}"
IsSynchronizedWithCurrentItem="True" />
</Grid>
</Window>
UserControl1.xaml:
<UserControl x:Class="WpfApplication1.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
MinWidth="200">
<UserControl.ContextMenu>
<ContextMenu >
<MenuItem Header="Change" Command="{Binding Path=ChangeCommand}"/>
</ContextMenu>
</UserControl.ContextMenu>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0">The name:</Label>
<TextBox Grid.Column="1" Text="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</UserControl>
Komp nyViewModel.cs:
public class CompanyViewModel
{
public ObservableCollection<PersonViewModel> Persons { get; set; }
public CompanyViewModel()
{
Persons = new ObservableCollection<PersonViewModel>();
Persons.Add(new PersonViewModel(new Person { Name = "Kalle" }));
Persons.Add(new PersonViewModel(new Person { Name = "Nisse" }));
Persons.Add(new PersonViewModel(new Person { Name = "Jocke" }));
}
}
PersonViewModel.cs:
public class PersonViewModel : INotifyPropertyChanged
{
Person _person;
TestCommand _testCommand;
public PersonViewModel(Person person)
{
_person = person;
_testCommand = new TestCommand(this);
}
public ICommand ChangeCommand
{
get
{
return _testCommand;
}
}
public string Name
{
get
{
return _person.Name;
}
set
{
if (value == _person.Name)
return;
_person.Name = value;
OnPropertyChanged("Name");
}
}
void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
TestCommand.cs:
public class TestCommand : ICommand
{
PersonViewModel _person;
public event EventHandler CanExecuteChanged;
public TestCommand(PersonViewModel person)
{
_person = person;
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
_person.Name = "Changed by command";
}
}
Person.cs:
public class Person
{
public string Name { get; set; }
}
Hallo Cameron. Glauben Sie, Ihre Technik hier irgendwie mit dem Problem ist ich hier beschrieben habe: http://stackoverflow.com/questions/833607/wpf-why-do-contextmenu-items-work-for-listbox-but-not- itemscontrol ... Ich bin nicht an einen Befehl gebunden, aber ich habe den Verdacht, dass es ein verwandtes Problem ist. –
Ich bin nicht von dieser Antwort überzeugt. Die Befehlsbindungen funktionieren für den Menüeintrag (er weiß, dass er das Ansichtsmodell binden muss) ... das Problem besteht darin, dass die Menüelemente nicht neu binden, wenn sich der Datenkontext aufgrund des Wechselns der Registerkarte ändert. Wenn es wegen ihnen nicht Teil des visuellen Baumes ist, wie kommt es zum ersten Mal funktioniert? – Schneider
@Schneider: Ich habe nicht gesagt, dass Bindungen in einem Menü nicht funktionieren, nur dass sie ihren Datenkontext nicht wie erwartet von ihren Elternkontexten erben. Ich würde sagen, dass die WPF-Bindungs-Engine den Kontext beim ersten Öffnen des Menüs einstellt und dann nicht aktualisiert, wenn sich die Registerkarte ändert. –