2011-03-05 21 views
13

Potansiyel olarak fazla satır olabilir bir veri kılavuzunu var için contextmenus oluşturun. Kullanıcı, satırlardan birini sağ tıklattıkça, her bir satır için bir bağlam menüsü göstermeli ve kullanıcı bu seçeneği tıklattığında bir eylemi (aynı eylemi ancak geçerli seçili satıra göre farklı veri öğesi) göstermem gerekir.datagrid satır

bunun için en iyi strateji nedir?

ContextMenuOpening olayını kullanarak menü oluştururken, içerik menüsü için "tembel bir yükleme" türünde olsa bile her satır için ContextMenu öğesinin aşırı olduğundan korkuyorum. Datagrid için sadece bir ContextMenu kullanmalı mıyım? Fakat bununla ben click olayı ile ilgili bazı daha fazla iş olurdu Bildiğim kadarıyla, eylemlerin bazı devre dışı kalacaktır biliyorum veya satırdaki bağlı etkin olarak vb doğru satır,

cevap

29

belirlemek için, bu yüzden hiçbir yoktur DataGrid için bir ContextMenu numaralı noktayı işaret eder.

ben satır düzeyinde içerik menüsüne bir örnek var.

<UserControl.Resources> 
    <ContextMenu x:Key="RowMenu" DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}"> 
     <MenuItem Header="Edit" Command="{Binding EditCommand}"/> 
    </ContextMenu> 
    <Style x:Key="DefaultRowStyle" TargetType="{x:Type DataGridRow}"> 
     <Setter Property="ContextMenu" Value="{StaticResource RowMenu}" /> 
    </Style> 
</UserControl.Resources> 

<DataGrid RowStyle="{StaticResource DefaultRowStyle}"/> 

DataGrid

bir komutlarla görünüm modellerinin listesi için bağlayıcı olması gerekir: bağlam menüsü UserControl kaynakları koleksiyonunda oluşturulan

public class ItemModel 
{ 
    public ItemModel() 
    { 
     this.EditCommand = new SimpleCommand 
     { 
      ExecuteDelegate = _ => MessageBox.Show("Execute"), 
      CanExecuteDelegate = _ => this.Id == 1 
     }; 
    } 
    public int Id { get; set; } 
    public string Title { get; set; } 
    public ICommand EditCommand { get; set; } 
} 

ve ben sadece bir nesne olduğunu düşünüyorum hangi datagrid satırları referans ile değil, değere göre bağlanır.

MainViewModel'un içinde Command için ContextMenu'un başka bir örneği.

<ContextMenu x:Key="RowMenu" DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}"> 
     <MenuItem Header="Edit" CommandParameter="{Binding}" 
        Command="{Binding DataContext.DataGridActionCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}" /> 
    </ContextMenu> 

Modeller:

public class MainViewModel 
{ 
    public MainViewModel() 
    { 
     this.DataGridActionCommand = new DelegateCommand<ItemModel>(m => MessageBox.Show(m.Title), m => m != null && m.Id != 2); 
    } 

    public DelegateCommand<ItemModel> DataGridActionCommand { get; set; } 
    public List<ItemModel> Items { get; set; } 
} 

public class ItemModel 
{ 
    public int Id { get; set; } 
    public string Title { get; set; } 
} 

Ama bir sorun olduğunu MenuItem degil' var ben DataGrid de CommandParameter nitelik Komuta özniteliği önce yerleştirilmelidir DataContext olarak doğru bir bakış modeline sahiptir varsayalım t CanExecute öğesi false değerini döndürürse, devre dışı bırakılmış öğe olarak görüntülenir. Olası geçici çözüm, ItemModel içinde bir ParentModel özelliğini kullanıyor, ancak ilk çözümden çok farklı değil.

public class ItemModel 
{ 
    public int Id { get; set; } 
    public string Title { get; set; } 
    public MainViewModel ParentViewModel { get; set; } 
} 

//Somewhere in the code-behind, create the main view model 
//and force child items to use this model as a parent model 
var mainModel = new MainViewModel { Items = items.Select(item => new ItemViewModel(item, mainModel)).ToList()}; 

Ve Menuıtem XAML simplier olacaktır:

<MenuItem Header="Edit" CommandParameter="{Binding}" 
       Command="{Binding ParentViewModel.DataGridActionCommand}" /> 
+0

teşekkürler örnek için, ben bir deneyin vereceğiz İşte yukarıda açıklanan çözümün örneğidir. Ama senin gibi aynı şüpheye sahibim, sadece bir Context Menu nesnesi var mı? Buna katlanmak zorunda kalacağım. – Jay

+0

Bunu test ettik ve aynı object.Nice olmalıdır böylece aynı değer sağlar satırların her birinin contextmenus Hash Kodu karşılaştıran! Her satır için gerçekten bir Komutaya ihtiyacım var mı? Ana ViewModel'ın içinde en üstte oturan bir ana Komut gibi kullanmak istedim. Bu sadece MenuItem'de Komut Bağlama ayarlanarak yapılabilir mi? Çalışmaya başlayamıyorum! lanet olsun ... – Jay

+0

@Jay Statik bir RoutedCommand demek istiyor musunuz? Aslında, satır düzeyindeki komutlar yerine olay işleyicileri veya genel komutları kullanmak mümkündür. Yarın benzer bir şeyi uygulamaya çalışacağım, ve eğer komutun kodunu ekleyebilseydin, bana yardım edecekti. – vorrtex