WPF DataGrid Tips

I’ve been struggling at work to use Microsoft’s WPF DataGrid (from their WPF Toolkit) to fulfil a fairly basic set of requirement. The following is simply a list of lessons learned.

  1. Remember to set the SortMemberPath for all DataGridTemplateColumns. Otherwise the column header is “inactive” and doesn’t allow sorting regardless of setting CanUserSort.
  2. Remember to set the ClipboardContentBinding for all DataGridTemplateColumns. Otherwise the column data will be copied to the clipboard as an empty string.

    <toolkit:DataGridTemplateColumn Header="Date of Birth"
                                                    
    SortMemberPath="DateOfBirth"
                                                    
    ClipboardContentBinding="{Binding DateOfBirth
    }">
          <
    toolkit:DataGridTemplateColumn.CellTemplate
    >
              <
    DataTemplate
    >
                  <
    TextBlock Text="{Binding DateOfBirth,Mode=OneWay,StringFormat=d}" Margin
    ="2,0,2,2"/>
              </
    DataTemplate
    >                    
          </
    toolkit:DataGridTemplateColumn.CellTemplate
    >
          <
    toolkit:DataGridTemplateColumn.CellEditingTemplate
    >
              <
    DataTemplate
    >
                  <
    toolkit:DatePicker SelectedDate="{Binding DateOfBirth,Mode
    =TwoWay}"/>
              </
    DataTemplate
    >
          </
    toolkit:DataGridTemplateColumn.CellEditingTemplate
    >
      </
    toolkit:DataGridTemplateColumn>
  3. As with other ItemsControls you will most likely want to redefine HighlightBrush and HighlightTextBrush to avoid the high contrast (and very old fashioned) row selection colours.
  4. Use Styles embedded in the DataGrid’s style’s Resources collection to override attributes of controls that will be used for editing. For example, setting the BorderThickness=”0” and Padding=”0” on the DatePicker.
  5. Watch out for implicit Styles that effect Button. The grid is made up of lots of buttons (grid, row and column headers) so having an implicit style define MinWidth or Margins can lead to some unsightly grid layouts.
  6. DataGridCheckBoxColumn doesn’t centre vertically and its default margin doesn’t seem to match the DataGridTextColumn. Setting the Margin for DataGridCheckBoxColumns to  “2”, or at least “0,2,0,0” seems to do the trick.
  7. Setting an EditingElementStyle for a DataGridTextBoxColumn to CharacterCasing=”Upper” is not honoured if the keystroke is used to enter edit mode. Requires a simple fix to the PrepareCellForEdit method in DataGridTextBoxColumn. Refer http://www.codeplex.com/wpf/Thread/View.aspx?ThreadId=36985.

                        // If text input started the edit, then replace the text with what was typed.
                    string inputText;
                    switch (textBox.CharacterCasing)
                    {
                        case CharacterCasing.Upper:
                            inputText = textArgs.Text.ToUpper();
                            break;
                        case CharacterCasing.Lower:
                            inputText = textArgs.Text.ToLower();
                            break;
                        default:
                            inputText = textArgs.Text;
                            break;
                    }
                    textBox.Text = inputText;
  8. Placing a DatePicker in a DataGridTemplateColumn doesn’t cause the DatePIcker to automatically gain focus when pressing F2 (enter edit). To get around that I overrode PrepareCellForEdit in DataGridTemplateColumn as follows:

        protected override object PrepareCellForEdit(FrameworkElement editingElement,
                                                                      RoutedEventArgs editingEventArgs)
        {
            editingElement.MoveFocus(new TraversalRequest(FocusNavigationDirection.First));
            return base.PrepareCellForEdit(editingElement, editingEventArgs);
        }

  9. The DatePicker uses the Enter key to highlight the date within its embedded TextBox. This is annoying when used in a DataGridTemplateColumn since the standard behaviour for the Enter key is to commit edits and move down a row. Commenting out this functionality in the DatePicker (within ProcessDatePickerKey) does the trick. 

            private bool ProcessDatePickerKey(KeyEventArgs e)
            {
                switch (e.Key)
                {
                    case Key.System:
                    {
                        switch (e.SystemKey)
                        {
                            case Key.Down: { if ((Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt)
                                {
                                    TogglePopUp();
                                    return true;
                                }
                                break;
                            }
                        }
                        break;
                    }
                  
    // Removing this functionality makes the control work better in the grid - ENTER goes to next row.
                  
    //case Key.Enter:
                  
    //{
                  
    //    SetSelectedDate();
                  
    //    return true;
                  
    //}
                }
                return false;
            }

Other Resources

 

What did you think of this article?




Trackbacks
  • No trackbacks exist for this entry.
Comments

Leave a comment

 Enter the above security code (required)

 Name

 Email (will not be published)

 Website

Your comment is 0 characters limited to 3000 characters.