The program uses several DataGrid with the same set of columns. There are a lot of them, so you don't want to just copy the code.

Tell me, is it possible to render only columns in a style?

Something like that:

 <Style x:Key="DataGridStyle" TargetType="{x:Type DataGrid}"> <Setter Property="DataGrid.Columns"> <Setter.Value> <DataGridTextColumn Header="Id" Binding="{Binding Product.Id}" /> <DataGridTextColumn Header="Название" Binding="{Binding Product.Title}" /> <DataGridTextColumn Header="Цена" Binding="{Binding Product.Price}" /> </Setter.Value> </Setter> </Style> 

Update

The program provides the user with 3 tables with goods: general, favorites and blacklist.

General table:

 <DataGrid ItemsSource="{Binding Products}" > <DataGrid.ContextMenu> <ContextMenu> <MenuItem Header="Открыть в браузере" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.SelectedItems}" Command="{Binding ResultsVM.OpenProductCommand}" /> <MenuItem Header="Добавить в избранное" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.SelectedItems}" Command="{Binding ResultsVM.PutToFavoritesCommand, IsAsync=True}" /> <MenuItem Header="Убрать из избранного" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.SelectedItems}" Command="{Binding ResultsVM.RemoveFromFavoritesCommand}" /> <MenuItem Header="Добавить в черный список" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.SelectedItems}" Command="{Binding ResultsVM.PutToBlackListCommand}" /> <MenuItem Header="Убрать из черного списка" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.SelectedItems}" Command="{Binding ResultsVM.RemoveFromBlacklistCommand}" /> <MenuItem Header="Удалить" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.SelectedItems}" Command="{Binding ResultsVM.DeleteCommand}" /> </ContextMenu> </DataGrid.ContextMenu> <DataGrid.Columns> <DataGridTextColumn Header="Id" Binding="{Binding Product.Id}" /> <DataGridTextColumn Header="Название" Binding="{Binding Product.Title}" /> <DataGridTextColumn Header="Цена" Binding="{Binding Product.Price}" /> </DataGrid.Columns> </DataGrid> 

Favorites:

 <DataGrid ItemsSource="{Binding Favorites}"> <DataGrid.ContextMenu> <ContextMenu> <MenuItem Header="Открыть в браузере" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.SelectedItems}" Command="{Binding ResultsVM.OpenProductCommand}" /> <MenuItem Header="Убрать из избранного" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.SelectedItems}" Command="{Binding ResultsVM.RemoveFromFavoritesCommand}" /> <MenuItem Header="Удалить" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.SelectedItems}" Command="{Binding ResultsVM.DeleteCommand}" /> </ContextMenu> </DataGrid.ContextMenu> <DataGrid.Columns> <DataGridTextColumn Header="Id" Binding="{Binding Product.Id}" /> <DataGridTextColumn Header="Название" Binding="{Binding Product.Title}" /> <DataGridTextColumn Header="Цена" Binding="{Binding Product.Price}" /> </DataGrid.Columns> </DataGrid> 
  • Maybe you need a UserControl ? What will be different in the tables? - VladD
  • @VladD, Yes, there are different elements in the tables. - trydex
  • Only the filling is different, and the rest is the same? - VladD
  • one
    Yeah, got it. And here I would add context menus through style. Style can be made the property UserControl 'a. I will write tomorrow, today is too late. - VladD
  • one
    Completed the answer, look. - VladD

1 answer 1

If you have equally arranged DataFrid 's and only different data in them, I would take out from in a separate UserControl :

 <UserControl x:Class="YourProject.ProductTable" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:YourProject" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> <DataGrid ItemsSource="{Binding}" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTextColumn Header="Id" Binding="{Binding Product.Id}" /> <DataGridTextColumn Header="Название" Binding="{Binding Product.Title}" /> <DataGridTextColumn Header="Цена" Binding="{Binding Product.Price}" /> </DataGrid.Columns> </DataGrid> </UserControl> 

At the same time in the code-behind UserControl 'and you can make procedures related to this DataGrid '.


Sample code for the context menu:

 <UserControl x:Class="YourProject.ProductTable" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:YourProject" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> <DataGrid ItemsSource="{Binding}" ContextMenu="{Binding GridContextMenu, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"> <DataGrid.Columns> <DataGridTextColumn Header="Id" Binding="{Binding Product.Id}" /> <DataGridTextColumn Header="Название" Binding="{Binding Product.Title}" /> <DataGridTextColumn Header="Цена" Binding="{Binding Product.Price}" /> </DataGrid.Columns> </DataGrid> </UserControl> 
 public partial class ProductTable : UserControl { public ProductTable() { InitializeComponent(); } public ContextMenu GridContextMenu { get { return (ContextMenu)GetValue(GridContextMenuProperty); } set { SetValue(GridContextMenuProperty, value); } } public static readonly DependencyProperty GridContextMenuProperty = DependencyProperty.Register( "GridContextMenu", typeof(ContextMenu), typeof(ProductTable)); } 

We tied the context menu to the GridContextMenu property (because the ContextMenu property is already taken), so you can use this:

 <local:ProductTable DataContext="{Binding Favorites}"> <local:ProductTable.GridContextMenu> <ContextMenu> <MenuItem Header="Открыть в браузере" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.SelectedItems}" Command="{Binding ResultsVM.OpenProductCommand}" /> <MenuItem Header="Убрать из избранного" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.SelectedItems}" Command="{Binding ResultsVM.RemoveFromFavoritesCommand}" /> <MenuItem Header="Удалить" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.SelectedItems}" Command="{Binding ResultsVM.DeleteCommand}" /> </ContextMenu> </local:ProductTable.GridContextMenu> </local:ProductTable> 

(Well, yes, setting the context menu can be easily rendered to the style.)