簡體   English   中英

WPF從父控件的DataContext綁定到操作

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM