我似乎无法从我的视图模型中绑定到命令来工作。上下文菜单的父级是一个列表菜单,它将其项源绑定到UserControl中称为ActiveArtists的属性。因此,我尝试将“ back”绑定到原始ViewModel。其中是另一个ViewModel的子级;与RelativeSource。但是我的方法似乎无效。
用于Tabitem的XAML
<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>
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));
}
更新:
我尝试实现建议的解决方案之一,但它仍未链接到命令。
这是更新的代码段。
<ListView.ContextMenu>
<ContextMenu FontSize="10" DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Delete Artist" Command="{Binding DeleteArtistCommand}" />
</ContextMenu>
</ListView.ContextMenu>
更新2:
使用的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;
}
}
答案 0 :(得分:2)
只需为您的ContextMenu设置DataContext:
<ContextMenu FontSize="10" DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
更新:
DeleteArtistCommand必须是属性,而不是字段。
public ICommand DeleteArtistCommand {get;set}