2013-12-04 3 views
0

Я использую UserControl, где основной элемент управления внутри - это datagrid. Все работает. Однако некоторые строки моего кода являются избыточными, поскольку я реализую один и тот же триггер в каждом из 48 столбцов.DataGridTemplateColumn InvokeCommandAction Template

Как создать шаблон для столбца datagridtemplate следующего фрагмента кода? Единственное отличие в каждом столбце - свойство bound. Все триггеры и форматирование одинаковы.

Буду признателен за вашу помощь!

<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

Так что я последовал предложению Шеридана с некоторыми изменениями, чтобы сделать его короче и проще. Хотя наш руководитель проекта предложил этот метод раньше, я понятия не имел, как его реализовать до ввода Sheridan. Kudos ему

Это код используемого 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> 
+0

@Sheridan - Привет, сэр, вы можете мне помочь? Я отметил вас, поскольку вы оказались одной из самых больших помощи в моем последнем запросе – eemwingg

ответ

0

Если DataTemplate s точно так же, а затем просто положить один в 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" /> 
... 

UPDATE >>>

Итак, если у вас есть Binding s внутри DataTemplate, тогда вам придется использовать UserControl. После этого вы сможете объявить DependencyProperty с для переменных свойств и связываться с ними из 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 > 
... 

Это еще много кода, но это намного меньше, чем раньше. Я не закончил этот пример для всех ваших свойств, но я предполагаю, что вы получите эту идею.

+0

спасибо за быстрый ответ sir. Я согласен, что вы правы, если все они будут одинаковыми. Однако каждая ячейка привязана к другому свойству. Только триггеры в каждой ячейке одинаковы. – eemwingg

+0

Спасибо! Чтобы свести к минимуму код, мы решили использовать только предыдущие триггеры s на TextBlock s в предложенном вами UserControl. Добавление UserControl к DataTemplate было очень простым. Просто установите фон и преобразователь UserControl как прежде. Я отредактирую свой вопрос, чтобы показать свою версию вашего предложения, если кто-то еще столкнется с подобной проблемой. – eemwingg