2016-09-07 71 views
1

我有一个包含数据的xaml数据网格,并且使用mvvm。 我希望我的单元格在我编辑完成后改变颜色。我不在乎保存颜色供以后使用,我只是想在单元格内容编辑完成后立即进行视觉更改。当按Enter键而不提交该行时移动到下一行

我能够通过使用一些代码背后实现上述行为(我想避免后面的代码,但因为它是纯视觉的,我想这是完全正常):

private void MyGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e) 
{ 
    FrameworkElement element = e.Column.GetCellContent(MyGrid.SelectedItem); 
    (element.Parent as DataGridCell).Background = (SolidColorBrush)Application.Current.Resources["EditedCellBackground"]; 
} 

这工作正常只要所选行具有焦点即可。换句话说,我可以在同一行上来回切换,并且编辑的单元格具有指定的背景颜色。

现在,问题是,当我按Enter键时,该行似乎被提交,光标移动到下一行,并且编辑的单元格的背景将返回到其原始颜色。

为了完整起见,这里是数据网格(上下浮动几个列):

<DataGrid Style="{StaticResource MainContentDataGridTheme}" 
        ItemsSource="{Binding Source={StaticResource Categories}}" 
        Grid.Row="1" 
        x:Name="MyGrid" 
        CellEditEnding="MyGrid_CellEditEnding"> 
    <DataGrid.GroupStyle> 
     <GroupStyle> 
      <GroupStyle.Panel> 
       <ItemsPanelTemplate> 
        <DataGridRowsPresenter/> 
       </ItemsPanelTemplate> 
      </GroupStyle.Panel> 
      <GroupStyle.ContainerStyle> 
       <Style TargetType="{x:Type GroupItem}"> 
        <Setter Property="Template"> 
         <Setter.Value> 
          <ControlTemplate TargetType="{x:Type GroupItem}"> 
           <Expander Name="expander" IsExpanded="True"> 
            <Expander.Header> 
             <StackPanel> 
              <TextBlock Text="{Binding Name}" FontWeight="DemiBold" FontSize="13" /> 
              <TextBlock Text="{Binding ItemCount, StringFormat={}Items: {0}}" FontSize="9" /> 
             </StackPanel> 
            </Expander.Header> 
            <ItemsPresenter /> 
           </Expander> 
          </ControlTemplate> 
         </Setter.Value> 
        </Setter> 
       </Style> 
      </GroupStyle.ContainerStyle> 
     </GroupStyle> 
    </DataGrid.GroupStyle> 
    <DataGrid.ColumnHeaderStyle> 
     <Style TargetType="DataGridColumnHeader"> 
      <Setter Property="HorizontalContentAlignment" Value="Right" /> 
      <Setter Property="ContentTemplate"> 
       <Setter.Value> 
        <DataTemplate> 
         <TextBlock TextWrapping="WrapWithOverflow" TextTrimming="CharacterEllipsis" Text="{Binding}"></TextBlock> 
        </DataTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 
    </DataGrid.ColumnHeaderStyle> 
    <DataGrid.Columns> 
     <DataGridTextColumn Width="25*" Binding="{Binding AppliedPercentage, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
          Header="Applied %"> 
      <DataGridTextColumn.CellStyle> 
       <Style> 
        <Setter Property="UIElement.IsEnabled" Value="{Binding IsEnabled}" /> 
        <Setter Property="TextBlock.TextAlignment" Value="Right" /> 
       </Style> 
      </DataGridTextColumn.CellStyle> 
    </DataGrid.Columns> 
</DataGrid> 

这里是DataGrid的风格:

<Style TargetType="DataGrid" x:Key="MainContentDataGridTheme"> 
    <Setter Property="AutoGenerateColumns" Value="False"/> 
    <Setter Property="ScrollViewer.CanContentScroll" Value="True"/> 
    <Setter Property="HeadersVisibility" Value="Column"/> 
    <Setter Property="AlternatingRowBackground" Value="{StaticResource DataGridAlternatingRowColor}" /> 
    <Setter Property="Margin" Value="10,10,10,0" /> 
    <Setter Property="CanUserDeleteRows" Value="False" /> 
    <Setter Property="CanUserAddRows" Value="False" /> 
    <Style.Resources> 
     <Style TargetType="DataGridCell"> 
      <Style.Setters> 
       <Setter Property="TextBlock.TextAlignment" Value="Right" /> 
      </Style.Setters> 
     </Style> 
    </Style.Resources> 
</Style> 

我如何才能让编辑单元格的背景同时保持输入密钥的行为?我不介意丢失行提交(UpdateSourceTrigger负责更新我的属性),但我绝对想要保持enter键的行为,也就是说:转到立即单元格向下(下一行,同一列),并且可以立即编辑内容。

感谢

回答

1

了一些研究之后,并与各试验的事情,我终于找到满足我需求的解决方法。

我更增添了几分代码背后做到以下几点:

  • 禁用该行致力于防止编辑的单元格的背景复位到原来的颜色。
  • 捕获KeyUp事件以人为重新创建回车键的行为。

所以,在XAML中,我添加了以下2个属性,以我的DataGrid:

RowEditEnding="MyGrid_RowEditEnding" 
KeyUp="MyGrid_KeyUp" 

而且在后面的代码,我实现了相应的方法:

private void MyGrid_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e) 
{ 
    // Prevents the row to be committed, but disable the "go to next row" behaviour 
    e.Cancel = true; 
} 

private void MyGrid_KeyUp(object sender, KeyEventArgs e) 
{ 
    var uiElement = e.OriginalSource as UIElement; 
    if (e.Key == Key.Enter && uiElement != null) 
    { 
     // Handle the key press as normal (-> validate the input) 
      e.Handled = true; 
      // Get the next element in the UI 
      var nextUIElement = uiElement.PredictFocus(FocusNavigationDirection.Down); 
      // Check if there if the next element is not null. This would occur with the last row of the grid. 
      if (nextUIElement != null) 
      { 
       // Check if the element is a cell, rather than something else like an expander for instance... 
       if (nextUIElement.GetType().Equals(typeof(DataGridCell))) 
       { 
        DataGridCellInfo nextCellInfo = new DataGridCellInfo((DataGridCell)nextUIElement); 
        // Set the selected row 
        PrelimsGrid.SelectedItem = nextCellInfo.Item; 
        // Set the selected cell. 
        PrelimsGrid.CurrentCell = nextCellInfo; 
       } 
       else 
       { 
        PrelimsGrid.SelectedItem = uiElement.MoveFocus(new TraversalRequest(FocusNavigationDirection.Down)); 
       } 
      } 
     } 
    } 
} 

虽然这为我工作,我会虚心承认我不是一个非常有经验的开发人员,我会很乐意阅读任何改进或替代解决方案。

相关问题