내가 아는 한, 일부 동작은 행에 따라 비활성화되거나 활성화되므로 아무 것도 없습니다. 하나의 ContextMenu
에 DataGrid
을 입력하십시오.
행 수준의 상황에 맞는 메뉴가 있습니다.
<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
는 명령보기 모델의 목록에 바인딩이 있어야 컨텍스트 메뉴가
UserControl
의 자원 수집에 생성됩니다
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; }
}
을 나는 단 하나의 객체가 생각하는 값이 아닌 참조에 의해 DataGrid 행과 연결됩니다.
안에 Command
에 대한 ContextMenu
의 또 다른 예가 있습니다.
<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>
모델 :
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; }
}
그러나 문제가 MenuItem
ISN이 '가 나는 DataGrid
또한 CommandParameter 속성은 Command 속성 앞에 위치해야 DataContext
으로 올바른 뷰 모델을 가지고 있다고 가정 CanExecute
이 false를 반환하면 비활성화 된 항목으로 표시됩니다. 가능한 해결 방법은 ItemModel
안에 ParentModel
속성을 사용하는 것이지만 첫 번째 해결 방법과 크게 다르지 않습니다.
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()};
그리고 MenuItem의 XAML에서이 더 간단 할 것이다 :
<MenuItem Header="Edit" CommandParameter="{Binding}"
Command="{Binding ParentViewModel.DataGridActionCommand}" />
덕분에 샘플을 위해, 나는 그것을 시도 줄거야 여기 는 전술 한 솔루션의 예입니다. 하지만, 당신과 마찬가지로, 같은 의심의 여지가 있습니다, 단 하나의 컨텍스트 메뉴 객체가 있습니까? 나는 이것을 파헤쳐 야 할 것이다. – Jay
나는 이것을 테스트하고 각 행의 ContextMenus의 해시 코드를 비교하여 동일한 값을 제공하므로 동일한 객체 여야합니다. 멋지다! 각 행에 대해 실제로 명령이 필요한가요? 기본 ViewModel 내부에있는 상위 명령과 같이 사용하고 싶었습니다. MenuItem에서 명령 바인딩을 조정하면됩니다. 나는 그것을 작동시킬 수 없다! 젠장 ... – Jay
@Jay 정적 RoutedCommand를 의미합니까? 실제로 행 수준 명령 대신 이벤트 처리기 또는 전역 명령을 사용할 수 있습니다. 내일 비슷한 것을 구현하려고합니다. 질문에 명령 코드를 추가하면 도움이 될 것입니다. – vorrtex