我将DataGridTextColumn
子类化为数值实现可编辑的DataGridColumn
。由于内部逻辑有些复杂,我想用NUnit对实现进行单元测试。但是,我无法弄清楚如何用测试数据填充它的单个单元格并触发其验证逻辑。任何帮助将不胜感激。
这是完整的实施:
using System;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace Presentation
{
public class DataGridNumericColumn : DataGridTextColumn
{
private static readonly Regex NonnumericChars = new Regex(@"\D");
private static readonly Regex NonnumericCharsExceptFirstMinus =
new Regex(@"(?<!^[^-]*)-|[^\d-]");
public bool AllowNegativeValues { private get; set; }
protected override object PrepareCellForEdit(
FrameworkElement editingElement, RoutedEventArgs editingEventArgs)
{
var textBox = (TextBox) editingElement;
textBox.PreviewTextInput += this.OnPreviewTextInput;
textBox.PreviewLostKeyboardFocus += this.OnPreviewLostKeyboardFocus;
DataObject.AddPastingHandler(textBox, this.OnPaste);
return base.PrepareCellForEdit(editingElement, editingEventArgs);
}
private void OnPreviewTextInput(object sender, TextCompositionEventArgs e)
{
if (this.AllowNegativeValues && e.Text == "-")
return;
if (!this.IsNumeric(e.Text))
e.Handled = true;
}
private void OnPreviewLostKeyboardFocus(
object sender, KeyboardFocusChangedEventArgs e)
{
var textBox = (TextBox) sender;
textBox.Text = this.ExtractNumericParts(textBox.Text);
}
private void OnPaste(object sender, DataObjectPastingEventArgs e)
{
if(!e.SourceDataObject.GetDataPresent(DataFormats.Text, true))
return;
var textBox = (TextBox)sender;
var preSelection = textBox.Text.Substring(0, textBox.SelectionStart);
var postSelection = textBox.Text.Substring(textBox.SelectionStart
+ textBox.SelectionLength);
var pastedText = (string)e.SourceDataObject.GetData(DataFormats.Text);
if (!this.IsNumeric(preSelection + pastedText + postSelection))
e.CancelCommand();
}
private bool IsNumeric(string text)
{
int number;
var isInt32 = Int32.TryParse(text, out number);
if (!this.AllowNegativeValues)
return isInt32 && number >= 0;
return isInt32;
}
private string ExtractNumericParts(string text)
{
if (this.IsNumeric(text))
return text;
text = this.RemoveIllegalChars(text);
return this.TrimDigitsToInt32Range(text);
}
private string RemoveIllegalChars(string text)
{
var illegalChars = this.AllowNegativeValues
? NonnumericCharsExceptFirstMinus
: NonnumericChars;
return illegalChars.Replace(text, string.Empty);
}
private string TrimDigitsToInt32Range(string numericText)
{
if (string.IsNullOrEmpty(numericText))
return "0";
return this.IsNumeric(numericText)
? numericText
: this.TrimDigitsToInt32Range(
numericText.Remove(numericText.Length - 1));
}
}
}
答案 0 :(得分:0)
意识到我试图做的是一件愚蠢的事。解决方案是将行为提取到可测试的类中。