I'm using a UserControl where the main control inside is a datagrid. All is working. However, some lines of my code are redundant since I implement the same trigger in each of the 48 columns.
How do I make a template for the datagridtemplatecolumn of the following code snippet? The only thing different in each column is the bound property. All the triggers and formatting are the same.
I would appreciate your help!
<DataGridTemplateColumn Header="5" MaxWidth="10">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock
Background="{Binding _5, Converter={StaticResource ResourceKey=hourSlotColorConverter}, UpdateSourceTrigger=PropertyChanged}"
Margin="-1">
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseLeftButtonDown">
<i:InvokeCommandAction
Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},
Path=DataContext.StartCellCommand}">
<i:InvokeCommandAction.CommandParameter>
<MultiBinding Converter="{StaticResource dgInfoConverter}">
<Binding Path="Column"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridCell}" />
<Binding Path="DataContext"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridCell}" />
</MultiBinding>
</i:InvokeCommandAction.CommandParameter>
</i:InvokeCommandAction>
</i:EventTrigger>
<i:EventTrigger EventName="PreviewMouseLeftButtonUp">
<i:InvokeCommandAction
Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},
Path=DataContext.LastCellCommand}">
<i:InvokeCommandAction.CommandParameter>
<MultiBinding Converter="{StaticResource dgInfoConverter}">
<Binding Path="Column"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridCell}" />
<Binding Path="DataContext"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridCell}" />
</MultiBinding>
</i:InvokeCommandAction.CommandParameter>
</i:InvokeCommandAction>
</i:EventTrigger>
<i:EventTrigger EventName="MouseMove">
<i:InvokeCommandAction
Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},
Path=DataContext.MouseDragCom}">
<i:InvokeCommandAction.CommandParameter>
<MultiBinding Converter="{StaticResource dgInfoConverter}">
<Binding Path="Column"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridCell}" />
<Binding Path="DataContext"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridCell}" />
</MultiBinding>
</i:InvokeCommandAction.CommandParameter>
</i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="" MaxWidth="10">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock
Background="{Binding _5_5, Converter={StaticResource ResourceKey=hourSlotColorConverter}, UpdateSourceTrigger=PropertyChanged}"
Margin="-1">
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseLeftButtonDown">
<i:InvokeCommandAction
Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},
Path=DataContext.StartCellCommand}">
<i:InvokeCommandAction.CommandParameter>
<MultiBinding Converter="{StaticResource dgInfoConverter}">
<Binding Path="Column"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridCell}" />
<Binding Path="DataContext"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridCell}" />
</MultiBinding>
</i:InvokeCommandAction.CommandParameter>
</i:InvokeCommandAction>
</i:EventTrigger>
<i:EventTrigger EventName="PreviewMouseLeftButtonUp">
<i:InvokeCommandAction
Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},
Path=DataContext.LastCellCommand}">
<i:InvokeCommandAction.CommandParameter>
<MultiBinding Converter="{StaticResource dgInfoConverter}">
<Binding Path="Column"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridCell}" />
<Binding Path="DataContext"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridCell}" />
</MultiBinding>
</i:InvokeCommandAction.CommandParameter>
</i:InvokeCommandAction>
</i:EventTrigger>
<i:EventTrigger EventName="MouseMove">
<i:InvokeCommandAction
Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},
Path=DataContext.MouseDragCom}">
<i:InvokeCommandAction.CommandParameter>
<MultiBinding Converter="{StaticResource dgInfoConverter}">
<Binding Path="Column"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridCell}" />
<Binding Path="DataContext"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridCell}" />
</MultiBinding>
</i:InvokeCommandAction.CommandParameter>
</i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="6" MaxWidth="10">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock
Background="{Binding _6, Converter={StaticResource ResourceKey=hourSlotColorConverter}, UpdateSourceTrigger=PropertyChanged}"
Margin="-1">
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseLeftButtonDown">
<i:InvokeCommandAction
Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},
Path=DataContext.StartCellCommand}">
<i:InvokeCommandAction.CommandParameter>
<MultiBinding Converter="{StaticResource dgInfoConverter}">
<Binding Path="Column"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridCell}" />
<Binding Path="DataContext"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridCell}" />
</MultiBinding>
</i:InvokeCommandAction.CommandParameter>
</i:InvokeCommandAction>
</i:EventTrigger>
<i:EventTrigger EventName="PreviewMouseLeftButtonUp">
<i:InvokeCommandAction
Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},
Path=DataContext.LastCellCommand}">
<i:InvokeCommandAction.CommandParameter>
<MultiBinding Converter="{StaticResource dgInfoConverter}">
<Binding Path="Column"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridCell}" />
<Binding Path="DataContext"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridCell}" />
</MultiBinding>
</i:InvokeCommandAction.CommandParameter>
</i:InvokeCommandAction>
</i:EventTrigger>
<i:EventTrigger EventName="MouseMove">
<i:InvokeCommandAction
Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},
Path=DataContext.MouseDragCom}">
<i:InvokeCommandAction.CommandParameter>
<MultiBinding Converter="{StaticResource dgInfoConverter}">
<Binding Path="Column"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridCell}" />
<Binding Path="DataContext"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridCell}" />
</MultiBinding>
</i:InvokeCommandAction.CommandParameter>
</i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
EDIT
So I followed Sheridan's suggestion with some revisions to make it shorter and simpler. Although our project leader suggested this method before, I had no idea on how to implement it prior to Sheridan's input. Kudos to him
This is the code for the UserControl we used. What it contains is exactly the same triggers we used from our original code above:
<UserControl x:Class="Widget5.View.DGInfo"
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:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:converter="clr-namespace:Widget5.Converter"
xmlns:dg="clr-namespace:Widget5.View"
mc:Ignorable="d"
d:DesignHeight="20" d:DesignWidth="20">
<UserControl.Resources>
<converter:DataGridInfoToParamConverter x:Key="dgInfoConverter" />
</UserControl.Resources>
<TextBlock Background="{Binding Background, RelativeSource={RelativeSource AncestorType={x:Type dg:DGInfo}}}" Margin="-1">
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseLeftButtonDown">
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},
Path=DataContext.StartCellCommand}" >
<i:InvokeCommandAction.CommandParameter>
<MultiBinding Converter="{StaticResource dgInfoConverter}">
<Binding Path="Column" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridCell}" />
<Binding Path="DataContext" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridCell}" />
</MultiBinding>
</i:InvokeCommandAction.CommandParameter>
</i:InvokeCommandAction>
</i:EventTrigger>
<i:EventTrigger EventName="PreviewMouseLeftButtonUp">
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},
Path=DataContext.LastCellCommand}" >
<i:InvokeCommandAction.CommandParameter>
<MultiBinding Converter="{StaticResource dgInfoConverter}">
<Binding Path="Column" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridCell}" />
<Binding Path="DataContext" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridCell}" />
</MultiBinding>
</i:InvokeCommandAction.CommandParameter>
</i:InvokeCommandAction>
</i:EventTrigger>
<i:EventTrigger EventName="MouseMove">
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},
Path=DataContext.MouseDragCom}" >
<i:InvokeCommandAction.CommandParameter>
<MultiBinding Converter="{StaticResource dgInfoConverter}">
<Binding Path="Column" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridCell}" />
<Binding Path="DataContext" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridCell}" />
</MultiBinding>
</i:InvokeCommandAction.CommandParameter>
</i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBlock>
</UserControl>
And on the DataGridTemplateColumn itself, we just added the UserControl(DGInfo) and set its background like we did before. Saved thousands of lines because of this.
<DataGrid ...>
...
<DataGridTemplateColumn Header="6" MaxWidth="10">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<View:DGInfo Background="{Binding _6, Converter={StaticResource ResourceKey=hourSlotColorConverter}, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
...
</DataGrid>