Wednesday, September 15, 2010

How to programmatically create a WPF data grid column which only accepts numeric values without using xaml

Use the following two classes to create the number text box column.

public class DataGridTemplateColumn DataGridNumberTextBoxColumn
{
public DataGridNumberTextBoxColumn(Binding binding)
{
var factory = new FrameworkElementFactory(typeof(NumberTextBox));
factory.SetValue(NumberTextBox.TextProperty, binding);
var cellTemplate = new DataTemplate {VisualTree = factory};
CellTemplate = cellTemplate;
}
}
}


public class NumberTextBox : TextBox
{
protected override void OnPreviewTextInput(System.Windows.Input.TextCompositionEventArgs e)
{
e.Handled = !AreAllValidNumericChars(e.Text);
base.OnPreviewTextInput(e);
}

static bool AreAllValidNumericChars(string str)
{
bool ret = true;
if (str == System.Globalization.NumberFormatInfo.CurrentInfo.CurrencyDecimalSeparator |
str == System.Globalization.NumberFormatInfo.CurrentInfo.CurrencyGroupSeparator |
str == System.Globalization.NumberFormatInfo.CurrentInfo.CurrencySymbol |
str == System.Globalization.NumberFormatInfo.CurrentInfo.NegativeSign |
str == System.Globalization.NumberFormatInfo.CurrentInfo.NegativeInfinitySymbol |
str == System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator |
str == System.Globalization.NumberFormatInfo.CurrentInfo.NumberGroupSeparator |
str == System.Globalization.NumberFormatInfo.CurrentInfo.PercentDecimalSeparator |
str == System.Globalization.NumberFormatInfo.CurrentInfo.PercentGroupSeparator |
str == System.Globalization.NumberFormatInfo.CurrentInfo.PercentSymbol |
str == System.Globalization.NumberFormatInfo.CurrentInfo.PerMilleSymbol |
str == System.Globalization.NumberFormatInfo.CurrentInfo.PositiveInfinitySymbol |
str == System.Globalization.NumberFormatInfo.CurrentInfo.PositiveSign)
return ret;

int l = str.Length;
for (int i = 0; i < l; i++)
{
char ch = str[i];
ret &= Char.IsDigit(ch);
}
return ret;
}
}

Crete the number textbox column as follows.

DataGridgrid = new DataGrid
{
ItemsSource = testSourceList,
IsReadOnly = false,
AutoGenerateColumns = false
};

grid.Columns.Add(new DataGridNumberTextBoxColumn(new Binding("BindValue")) { Header = "TestHeader"});

0 comments:

Post a Comment