[英]WPF Binding To Action from Parent Control's DataContext
I can't seem to get the binding to a command from my view model to work. 我似乎无法从我的视图模型中绑定到命令来正常工作。 The parent of the context menu which is a listmenu binds its itemssource to a property in the UserControl called ActiveArtists. 上下文菜单的父级是一个列表菜单,它将其项源绑定到UserControl中称为ActiveArtists的属性。 As so I tried to bind "back" to the original ViewModel; 因此,我尝试将“ back”绑定到原始ViewModel。 of which is a child of another ViewModel; 其中是另一个ViewModel的子级; with RelativeSource. 与RelativeSource。 However the way I did it doesn't seem to work. 但是我的方法似乎不起作用。
XAML for the tabitem XAML用于Tabitem
<TabItem DataContext="{Binding Children[1]}" Header="Database">
<Grid Background="#FFE5E5E5" IsEnabled="True">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ListView x:Name="ArtistListView" ItemsSource="{Binding ActiveArtists}" SelectedItem="{Binding SelectedArtist}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled" Margin="10,10,5,10">
<ListView.ContextMenu>
<ContextMenu FontSize="10">
<MenuItem Header="Delete Artist" Command="{Binding Path=DeleteArtistCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabItem}}}" />
</ContextMenu>
</ListView.ContextMenu>
<ListView.View>
<GridView>
<GridViewColumn Header="Artist" DisplayMemberBinding="{Binding Name}" Width="150"/>
</GridView>
</ListView.View>
</ListView>
<ListView x:Name="listView1" ItemsSource="{Binding ActiveAlbums}" SelectedItem="{Binding SelectedAlbum}" Margin="5,10,5,10" Grid.Column="1">
<ListView.View>
<GridView>
<GridViewColumn Header="Album" DisplayMemberBinding="{Binding Name}"
Width="150"/>
</GridView>
</ListView.View>
</ListView>
<ListView x:Name="listView2" ItemsSource="{Binding ActiveTracks}" SelectedItem="{Binding SelectedTrack}" Margin="5,10,10,10" Grid.Column="2">
<ListView.View>
<GridView>
<GridViewColumn Header="Track" DisplayMemberBinding="{Binding Name}"
Width="150"/>
</GridView>
</ListView.View>
</ListView>
Code for the MainWindowViewModel MainWindowViewModel的代码
public class MainWindowViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private MusicLogClient _musicLog;
ObservableCollection<object> _children;
public ObservableCollection<object> Children { get { return _children; } }
public MainWindowViewModel()
{
string rootPath = "C:\\Programs\\MusicLog\\UserData\\";
_musicLog = new MusicLogClient(new UserSettings(rootPath+"database.xml", rootPath+"credentials.xml"));
_children = new ObservableCollection<object>();
_children.Add(new ArtistEntryViewModel(_musicLog));
_children.Add(new DatabaseViewModel(_musicLog));
}
Update: 更新:
I tried implementing one of the solutions proposed but it still doesn't link to the command. 我尝试实现建议的解决方案之一,但它仍未链接到命令。
This is the updated code snippet. 这是更新的代码段。
<ListView.ContextMenu>
<ContextMenu FontSize="10" DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Delete Artist" Command="{Binding DeleteArtistCommand}" />
</ContextMenu>
</ListView.ContextMenu>
Update 2: 更新2:
ViewModel used - 使用的ViewModel-
public class DatabaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private MusicLogClient _musicLog;
public ICommand DeleteArtistCommand;
private ObservableCollection<Artist> _activeArtists;
public ObservableCollection<Artist> ActiveArtists
{
get
{
return _activeArtists;
}
set
{
_activeArtists = value;
RaisePropertyChanged("DatabaseArtists");
}
}
private Artist _selectedArtist;
public Artist SelectedArtist
{
get
{
return _selectedArtist;
}
set
{
_selectedArtist = value;
RaisePropertyChanged("SelectedArtist");
GetDatabaseAlbums();
ActiveTracks = null;
}
}
private ObservableCollection<Album> _activeAlbums;
public ObservableCollection<Album> ActiveAlbums
{
get
{
return _activeAlbums;
}
set
{
_activeAlbums = value;
RaisePropertyChanged("ActiveAlbums");
}
}
private Album _selectedAlbum;
public Album SelectedAlbum
{
get
{
return _selectedAlbum;
}
set
{
_selectedAlbum = value;
RaisePropertyChanged("SelectedAlbum");
GetDatabaseTracks();
}
}
private ObservableCollection<Track> _activeTracks;
public ObservableCollection<Track> ActiveTracks
{
get
{
return _activeTracks;
}
set
{
_activeTracks = value;
RaisePropertyChanged("ActiveTracks");
}
}
private Track _selectedTrack;
public Track SelectedTrack
{
get
{
return _selectedTrack;
}
set
{
_selectedTrack = value;
RaisePropertyChanged("SelectedTrack");
}
}
public DatabaseViewModel(MusicLogClient musicLog)
{
_musicLog = musicLog;
GetDatabaseArtists();
LoadCommands();
}
private void GetDatabaseArtists()
{
ActiveArtists = _musicLog.GetArtists().ToObservableCollection();
}
private void GetDatabaseAlbums()
{
if (SelectedArtist != null)
{
ActiveAlbums = _musicLog.GetAlbums(SelectedArtist).ToObservableCollection();
}
}
private void GetDatabaseTracks()
{
if (SelectedAlbum != null)
{
ActiveTracks = _musicLog.GetTracks(SelectedAlbum).ToObservableCollection();
}
}
private void LoadCommands()
{
DeleteArtistCommand = new CustomCommand(DeleteArtist, CanDeleteArtist);
}
private void DeleteArtist(object obj)
{
_musicLog.RemoveArtist(SelectedArtist);
}
private bool CanDeleteArtist(object obj)
{
if (SelectedArtist != null)
{
return true;
}
return false;
}
}
Just set DataContext for your ContextMenu: 只需为您的ContextMenu设置DataContext:
<ContextMenu FontSize="10" DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
Update: 更新:
DeleteArtistCommand must be a property, not a field. DeleteArtistCommand必须是属性,而不是字段。
public ICommand DeleteArtistCommand {get;set}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.