2012-09-20 3 views
1

마스터 - 세부 레코드를 보관하도록 설정된 WPF MVVM 응용 프로그램에 Xceed DataGrid가 있습니다. 자식 행을 선택하면 ViewModel에서 선택한 자식을 검색하도록합니다. 나는 이것을 0 번 코드 숨김으로하고 싶다. 컨텍스트 메뉴를 클릭하면 선택한 항목에 대한 작업을 실행하는 코드가 작성되었습니다. 부모가 선택되면 올바르게 작동하지만 자식을 선택하면 항상 null을 반환합니다.Xceed Datagrid가 자식 선택시 SelectedItem을 잃습니다

내 XAML은 다음과 같습니다 : 내가 함께 내가 acheive하려고 무엇을 매우 단순화 된 버전 뒀다

<Window x:Class="MasterDetailSelection.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:xcdg="clr-namespace:Xceed.Wpf.DataGrid;assembly=Xceed.Wpf.DataGrid.v4.2" 
    Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <Grid.Resources> 
      <xcdg:DataGridCollectionViewSource x:Key="cvs_parents" Source="{Binding Path=Parents}"> 
       <xcdg:DataGridCollectionViewSource.DetailDescriptions> 
        <xcdg:PropertyDetailDescription RelationName="Children" 
                AutoCreateDetailDescriptions="False"> 
        </xcdg:PropertyDetailDescription> 
       </xcdg:DataGridCollectionViewSource.DetailDescriptions> 
      </xcdg:DataGridCollectionViewSource> 
     </Grid.Resources> 
     <xcdg:DataGridControl x:Name="ParentGrid" 
           NavigationBehavior="RowOnly" 
           ItemsSource="{Binding Source={StaticResource cvs_parents}}" 
           SelectedItem="{Binding SelectedItem}" 
      AutoCreateDetailConfigurations="True" 
           ReadOnly="True"> 
      <xcdg:DataGridControl.ContextMenu> 
       <ContextMenu DataContext="{Binding PlacementTarget, RelativeSource={RelativeSource Self}}"> 
        <MenuItem Header="Execute Command" 
           CommandParameter="{Binding DataContext.SelectedItem}" 
           Command="{Binding DataContext.SampleCommand}" /> 
       </ContextMenu> 
      </xcdg:DataGridControl.ContextMenu> 
     </xcdg:DataGridControl> 

    </Grid> 
</Window> 

보기 모델은 다음과 같습니다

namespace MasterDetailSelection 
{ 
    using System; 
    using System.Collections.Generic; 
    using System.Collections.ObjectModel; 
    using System.ComponentModel; 
    using Microsoft.Practices.Composite.Presentation.Commands; 

    public class ViewModel : INotifyPropertyChanged 
    { 
     private ObservableCollection<Parent> _parents; 
     public event PropertyChangedEventHandler PropertyChanged; 
     private DelegateCommand<Object> _sampleCommand; 
     private object _selectedItem; 

     public ObservableCollection<Parent> Parents 
     { 
      get { return _parents; } 

      set 
      { 
       _parents = value; 
       OnPropertyChanged("Parents"); 
      } 
     } 

     public DelegateCommand<Object> SampleCommand 
     { 
      get 
      { 
       if (_sampleCommand == null) 
       { 
        _sampleCommand = new DelegateCommand<object>(ExecuteSampleCommand, CanExecuteSampleCommand); 
        OnPropertyChanged("SampleCommand"); 
       } 
       return _sampleCommand; 
      } 
     } 

     public bool CanExecuteSampleCommand(Object commandParameter) 
     { 
      return true; 
     } 

     public void ExecuteSampleCommand(Object commandParameter) 
     { 
      Console.WriteLine("ExecuteSampleCommand"); 
     } 

     public object SelectedItem 
     { 
      get { return _selectedItem; } 
      set 
      { 
       if (_selectedItem != value) 
       { 
        _selectedItem = value; 
        OnPropertyChanged("SelectedItem"); 
       } 
      } 
     } 

     public void LoadParents() 
     { 
      var parents = new ObservableCollection<Parent>() 
       { 
        new Parent() 
         { 
          Id=1, 
          Description = "Parent1", 
          Children = new List<Child>(){new Child() {Id = 1, Description = "Child1"} } 
         } 
       }; 

      Parents = parents; 
     } 

     private void OnPropertyChanged(string propertyName) 
     { 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
    } 
} 

은 2있다 간단한 개체 :

public class Parent 
{ 
    public int Id { get; set;} 
    public string Description { get; set;} 
    public IEnumerable<Child> Children { get; set;} 
} 
public class Child 
{ 
    public int Id { get; set; } 
    public string Description { get; set; } 
} 
내가 부모 행을 선택 할 때마다

var viewModel = new ViewModel(); 
var window = new MainWindow(); 
window.DataContext = viewModel; 
viewModel.LoadParents(); 
window.Show(); 

는 selectedItem가 세터는 인구 객체로 호출됩니다

App.xaml.cs를의 OnStartup 오버라이드는 다음이 포함되어 있습니다. 하위 행을 선택하면 동일한 설정자가 호출되지만 null 값을가집니다.

상황에 맞는 메뉴가 자식 행에서 클릭되었을 때 선택한 항목에 대한 참조를 얻을 수있는 방법이 있습니까? 코드 숨김없이이 작업을 수행하십시오. 그렇지 않다면 코드 숨김으로 가능합니까?

답변

0

아마도 아래와 같이 셀이나 행에 상황에 맞는 메뉴를 설정해야합니다. 그런 다음 적절한 모델을 명령에 보낼 수 있습니다. 아래 예제에서는 실제 VM을 바인딩하는 정적 로케이터 클래스를 사용합니다.

<Style TargetType="{x:Type xcdg:DataCell}"> 
    <Setter Property="ContextMenu" Value="{StaticResource CellContextMenu}"> 
     <Setter.Value> 
      <ContextMenu> 
       <MenuItem Header="Execute Command" 
          CommandParameter="{Binding}" 
          Command="{Binding Source={StaticResource Locator} Path=ViewModel.SampleCommand}" /> 
      </ContextMenu> 
     </Setter.Value> 
    </Setter> 
</Style>