2014-09-10 84 views
2

我有一個標準的WPF <DataGrid>具有特定列(即不自動生成)。它通過將ItemsSource設置爲具有各種屬性的對象列表,並將DataGrid中的各列綁定(通過XAML中的Binding =「{Binding XXX}」)綁定到適當的屬性,從而在C#中進行填充。想要爲每個WPF數據網格單元格定製上下文菜單

現在,我想要在用戶右鍵單擊單元格時顯示上下文菜單,但菜單的內容應根據用戶單擊的單元格而有所不同。我無法弄清楚如何做到這一點,所以任何建議,將不勝感激。

理想的情況是給定列(而不是列標題)中的每個單元格將具有相同的上下文菜單,並且不同的列將具有不同的上下文菜單。如果菜單中的某些項不適用於該特定行,則某些菜單項可能會變灰。菜單的內容可以根據用戶點擊哪一列進行硬編碼,但是我必須有某種動態機制(理想情況下通過C#函數,而不是無窮無盡的XAML)來決定何時灰顯菜單物品和什麼時候不到。

編輯:我很好的解決方案,讓我添加菜單項動態(在C#代碼)菜單出現,如果我可以告訴它出現的單元格。其實我更喜歡這樣的事情,因爲我喜歡C#比XAML更好。

回答

1

下面是一個完整的示例:

的VM:

public class MainViewModel : INotifyPropertyChanged 
{ 
    public ObservableCollection<Employee> Employees { get; set; } 

    public RelayCommand<Employee> FireCommand { get; set; } 

    private Employee selectedEmployee; 
    public Employee SelectedEmployee 
    { 
     get { return selectedEmployee; } 
     set 
     { 
      if (value != selectedEmployee) 
      { 
       selectedEmployee = value; 
       PropertyChanged(this, new PropertyChangedEventArgs("SelectedEmployee")); 
       FireCommand.RaiseCanExecuteChanged(); 
      } 
     } 
    } 

    public MainViewModel() 
    { 
     Employees = new ObservableCollection<Employee> 
     { 
      new Employee{ Name = "Mickey Mouse", CanBeFired = true }, 
      new Employee{ Name = "Barack Obama", CanBeFired = true }, 
      new Employee{ Name = "Chuck Norris", CanBeFired = false /* Don't even try!!! */ } 
     }; 

     foreach (Employee e in Employees) 
     { 
      e.PropertyChanged += (s, a) => 
       { 
        if (a.PropertyName == "CanBeFired") 
        { 
         FireCommand.RaiseCanExecuteChanged(); 
        } 
       }; 
     } 

     FireCommand = new RelayCommand<Employee>(_ => Employees.Remove(SelectedEmployee), _ => SelectedEmployee != null && SelectedEmployee.CanBeFired); 
    } 

    public event PropertyChangedEventHandler PropertyChanged = delegate { }; 
} 

的XAML:

<DataGrid ItemsSource="{Binding Employees}" SelectedValue="{Binding SelectedEmployee}" AutoGenerateColumns="False"> 
    <DataGrid.Columns> 
     <DataGridTemplateColumn> 
      <DataGridTemplateColumn.CellTemplate> 
       <DataTemplate> 
        <TextBlock Text="{Binding Name}"></TextBlock> 
       </DataTemplate> 
      </DataGridTemplateColumn.CellTemplate> 
     </DataGridTemplateColumn> 
     <DataGridCheckBoxColumn Binding="{Binding CanBeFired,UpdateSourceTrigger=PropertyChanged}"></DataGridCheckBoxColumn> 
    </DataGrid.Columns> 
    <DataGrid.ContextMenu> 
     <ContextMenu> 
      <MenuItem Header="Fire" Command="{Binding FireCommand}"> 
      </MenuItem> 
     </ContextMenu> 
    </DataGrid.ContextMenu> 
</DataGrid> 

注意,你並不需要一個泛型RelayCommand因此可以忽略通用參數和lambda的_參數。

+0

我很困惑 - 這會給我在每一列中的相同的1項上下文菜單(即「火」),對不對?我需要爲不同的列有不同的上下文菜單。所有文本列,如果有幫助。因此,例如,在第一列中,我希望有一個上下文菜單,其中顯示「Fire」,但在第二列上我想要一個帶有「This」,「That」和「The Other」的3項上下文菜單。 – MarkV 2014-09-11 12:26:13

+0

我會說ContextMenu必須關聯到DataTemplate中的TextBlock – rpaulin56 2016-04-28 13:59:52

+0

@Pragmateek這很有幫助。你可以發佈RelayCommand的代碼嗎? – vdidxho 2018-03-01 13:55:39

相關問題