DataGridTemplateColumn InvokeCommandAction模板

时间:2013-12-04 06:36:24

标签: wpf datagridtemplatecolumn celltemplate

我正在使用UserControl,其中主控件是数据网格。 一切正常。 但是,由于我在48列中的每一列中实现了相同的触发器,因此我的代码中的某些行是多余的。

如何为以下代码段的datagridtemplate列创建模板? 每列中唯一不同的是绑定属性。所有的触发器和格式都是一样的。

感谢您的帮助!

<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>

修改

因此,我遵循Sheridan的建议进行了一些修改,以使其更简短。虽然我们的项目负责人之前曾提出过这种方法,但我还是不知道如何在谢里丹的投入之前实施它。感谢他

这是我们使用的UserControl的代码。它包含的内容与我们上面原始代码中使用的触发器完全相同:

<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>

在DataGridTemplateColumn本身,我们刚刚添加了UserControl(DGInfo)并像之前一样设置了它的背景。因此节省了数千行。

<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>

1 个答案:

答案 0 :(得分:0)

如果您的DataTemplate完全相同,那么只需将其中一个放入Resources部分,然后只需引用它:

<DataGrid.Resources>
    <DataTemplate x:Key="TheDataTemplate">
        <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>
</DataGrid.Resources>
...
<DataGridTemplateColumn CellTemplate="{StaticResource TheDataTemplate}" 
Header="" MaxWidth="10" />
...

更新&gt;&gt;&gt;

好的,如果您在Binding内有DataTemplate个不同的内容,那么您将不得不使用UserControl。然后,您就可以为变量属性声明DependencyProperty s并从DataGridColumn绑定到它们:

<UserControl ... >
    <TextBlock
        Background="{Binding Background, RelativeSource={RelativeSource AncestorType={x:Type yourXmlNamespacePrefix:YourUserControl}}}"
        Margin="-1">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="PreviewMouseLeftButtonDown">
                <i:InvokeCommandAction
                    Command="{Binding StartCellCommand, RelativeSource={RelativeSource AncestorType={x:Type yourXmlNamespacePrefix:YourUserControl}}}">
                    <i:InvokeCommandAction.CommandParameter>
                        <MultiBinding Converter="{StaticResource dgInfoConverter}">
                            <Binding Path="Column"
                                     RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type yourXmlNamespacePrefix:YourUserControl}}" />
                            <Binding Path="SomeProperty"
                                     RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type yourXmlNamespacePrefix:YourUserControl}}" />
                        </MultiBinding>
                    </i:InvokeCommandAction.CommandParameter>
                </i:InvokeCommandAction>
            </i:EventTrigger>
            ...
        </i:Interaction.Triggers>
    </TextBlock>
</UserControl>

如果您为每个不同的DependencyProperty定义Binding,那么您将能够像这样设置它们:

...
<DataGridTemplateColumn Header="" MaxWidth="10">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <yourXmlNamespacePrefix:YourUserControl Background="{Binding _5_5, 
Converter={StaticResource  ResourceKey=hourSlotColorConverter}, 
UpdateSourceTrigger=PropertyChanged}" StartCellCommand="{Binding RelativeSource=
{RelativeSource AncestorType={x:Type DataGrid}}, Path=DataContext.StartCellCommand}" 
Column="{Binding Column, RelativeSource={RelativeSource AncestorType={x:Type 
DataGridCell}}}" SomeProperty="{Binding DataContext, RelativeSource={RelativeSource 
AncestorType={x:Type DataGridCell}}}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn >
...

它仍然是很多代码,但它比以前少得多。我没有为你的所有属性完成这个例子,但我猜你会得到这个想法。