Quantcast
Channel: Pubu's Travel Blog
Viewing all articles
Browse latest Browse all 31

WPF data grid bound column for numeric values with solution to double tab focus issue

$
0
0
This solution will solve the headache of pressing tab two times or mouse double click to make the grid cell editable. This solution can be customized to use with DataGridTemplateColumn as well. I have created the code in more generalized way as you can use it easily.

public class DataGridINumberTextBoxColumn : DataGridBoundColumn
{

protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
{
DataGridCellHelper helper = new DataGridCellHelper();
helper.SetFocus(cell);

var elem = new NumberTextBox() { AllowNull = false, Focusable = true, BorderThickness = new Thickness(0) };
BindingBase binding = Binding;
if (binding != null)
{
elem.SetBinding(TextBox.TextProperty, binding);
}
else
{
BindingOperations.ClearBinding(elem, TextBox.TextProperty);
}
return elem;
}

protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
{
DataGridCellHelper helper = new DataGridCellHelper();
helper.SetFocus(cell);

var elem = new INumberTextBox() { AllowNull = false, Focusable = true, BorderThickness = new Thickness(0) };
BindingBase binding = Binding;
if (binding != null)
{
elem.SetBinding(TextBox.TextProperty, binding);
}
else
{
BindingOperations.ClearBinding(elem, TextBox.TextProperty);
}
return elem;
}
}

internal class DataGridCellHelper
{
private DataGrid dataGrid;

// Sets the focus of the cell child with the events of the Data grid which that cell belongs to
public void SetFocus(DataGridCell cell)
{
cell.KeyDown += CellKeyDown;
dataGrid = FindVisualParent(cell);
dataGrid.CurrentCellChanged += DataGridCurrentCellChanged;
dataGrid.PreparingCellForEdit += DataGridPreparingCellForEdit;
}

// Trap TAB+SHIFT key press and move focus to the previous UI control
instance containing the event data.public void CellKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Tab && (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
MoveToPreviousControl(e.OriginalSource);
}

// Moves focus to previous control of sender.
private static void MoveToPreviousControl(object sender)
{
var element = (TextBox) sender;
if (element != null) element.MoveFocus(new TraversalRequest(FocusNavigationDirection.Previous));
}

private void DataGridCurrentCellChanged(object sender, EventArgs e)
{
dataGrid.BeginEdit();
}

private static void DataGridPreparingCellForEdit(object sender, DataGridPreparingCellForEditEventArgs e)
{
var element = e.EditingElement;
var childElem = FindVisualChild(element);
if (childElem != null) childElem.Focus();
}

// Finds the visual parent of the given UI element
private static T FindVisualParent(UIElement element) where T : UIElement
{
UIElement parent = element;
while (parent != null)
{
T elm = parent as T;
if (elm != null)
{
return elm;
}

parent = VisualTreeHelper.GetParent(parent) as UIElement;
}
return null;
}

// Finds the visual child of the given UI element
private static T FindVisualChild(UIElement element) where T : UIElement
{
UIElement child = element;
while (child != null)
{
T elm = child as T;
if (elm != null)
{
return elm;
}

child = VisualTreeHelper.GetChild(child,0) as UIElement;
}
return null;
}
}

If you need to see the code of the NumberTextBox go to the following post.
http://pubudini.blogspot.com/2010/09/how-to-programmatically-create-wpf-data.html


Reference : http://www.cwithb.com/2009/11/wpf-datagrid-and-the-dreaded-double-tab-focus-issue/

Viewing all articles
Browse latest Browse all 31

Latest Images

Trending Articles





Latest Images