[英]WPF Binding To Action from Parent Control's DataContext
我似乎無法從我的視圖模型中綁定到命令來正常工作。 上下文菜單的父級是一個列表菜單,它將其項源綁定到UserControl中稱為ActiveArtists的屬性。 因此,我嘗試將“ back”綁定到原始ViewModel。 其中是另一個ViewModel的子級; 與RelativeSource。 但是我的方法似乎不起作用。
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>
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;
}
}
只需為您的ContextMenu設置DataContext:
<ContextMenu FontSize="10" DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
更新:
DeleteArtistCommand必須是屬性,而不是字段。
public ICommand DeleteArtistCommand {get;set}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.