1

I have an application with two DataGrid controls. And although their ItemsSource are bound to different collections, their item type, columns, styles and event handlers are exactly the same.

As their XAML codes are growing bigger and bigger, how can I create the same "content" and reuse it in both DataGrids?

What I currently have is:

<DataGrid x:Name="LeftGrid" 
         ItemsSource="{Binding LeftCollection}" 
         Grid.Column="0"
         CanUserAddRows="False" CanUserDeleteRows="False" AutoGenerateColumns="False">

    <!--exactly the same code from this forward-->
    <DataGrid.Resources>
        <Style TargetType="DataGridRow">
            <EventSetter Event="MouseDoubleClick" Handler="DataGridRow_MouseDoubleClick"/>
        </Style>
    </DataGrid.Resources>
    <DataGrid.Columns>
        <DataGridTextColumn Header="Type" Binding="{Binding Type, Mode=OneWay}" IsReadOnly="True"/>
        <DataGridTextColumn Header="Status" Binding="{Binding Status, Mode=OneWay}" IsReadOnly="True"/>
        ...............................
        ................................
        .....................................
    </DataGrid.Columns>
</DataGrid>

Then I have "exaclty" the same datagrid copied whose only changes are Name, Grid.Column and ItemsSource (only the three first rows of the XAML):

<DataGrid x:Name="RightGrid"
         ItemsSource="{Binding RightCollection}" 
         Grid.Column="1"
         CanUserAddRows="False" CanUserDeleteRows="False" AutoGenerateColumns="False">
      
    <!--exactly the same code from this forward-->
    <DataGrid.Resources>
        <Style TargetType="DataGridRow">
            <EventSetter Event="MouseDoubleClick" Handler="DataGridRow_MouseDoubleClick"/>
        </Style>
    </DataGrid.Resources>
    <DataGrid.Columns>
        <DataGridTextColumn Header="Type" Binding="{Binding Type, Mode=OneWay}" IsReadOnly="True"/>
        <DataGridTextColumn Header="Status" Binding="{Binding Status, Mode=OneWay}" IsReadOnly="True"/>
        ...............................
        ................................
        .....................................
    </DataGrid.Columns>
</DataGrid>
Daniel Möller
  • 84,878
  • 18
  • 192
  • 214

1 Answers1

1

The easiest way at the first glance is to put it to the UserControl and use it in the main view.

<UserControl x:Class="YourNameSpace.UserControl1"
             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" 
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.Resources>
    </UserControl.Resources>
    <Grid>
        <DataGrid ItemsSource="{Binding}">
            <!-- ... -->
        </DataGrid>
    </Grid>
</UserControl>

Which you can use then:

xmlns:local="clr-namespace:YourNameSpace"
<local:UserControl1 x:Name="LeftGrid" DataContext="{Binding LeftCollection}" Grid.Column="0"/>
<local:UserControl1 x:Name="RightGrid" DataContext="{Binding RightCollection}" Grid.Column="1"/>

If you don't want to use a collection as DataContext for the whole UserControl, then you can of course create a dedicated dependency property for collection in the UserControl and bind it to the DataGrid.ItemsSource.

Rekshino
  • 6,954
  • 2
  • 19
  • 44
  • For the original question, your answer is great. But in case anyone needs more properties for the control, this post explains how to add and use them: https://stackoverflow.com/questions/11226843/data-binding-in-wpf-user-controls – Daniel Möller Jun 11 '21 at 18:58