我是WPF的新手, 我想阻止用户输入字符,例如字符“ - ”,所以 我使用以下代码创建了自定义DataGridTextColumn:
public class DataGridNumericColumn : DataGridTextColumn
{
protected override object PrepareCellForEdit(FrameworkElement editingElement, RoutedEventArgs editingEventArgs)
{
var textBox = (TextBox) editingElement;
textBox.PreviewTextInput += OnPreviewTextInput;
return base.PrepareCellForEdit(editingElement, editingEventArgs);
}
private void OnPreviewTextInput(object sender, TextCompositionEventArgs e)
{
var textBox = (TextBox)sender;
if (e.Text == "-")
return;
if (!this.IsNumeric(e.Text))
e.Handled = true;
}
}
和XAML:
<ZF:ZFDataGrid
Grid.Row="4" Grid.Column="0"
HorizontalAlignment="Stretch" VerticalAlignment="Top"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
CanUserAddRows="True"
CanUserDeleteRows="False"
CanUserResizeRows="False"
CanUserReorderColumns="False"
CanUserSortColumns="False"
IsSynchronizedWithCurrentItem="True"
SelectionUnit="Cell"
SelectionMode="Single"
Margin="3,3,3,0"
AutoGenerateColumns="False"
AlternatingRowBackground="WhiteSmoke"
RowHeaderWidth="30"
FontSize="18"
ItemsSource="{Binding POSModel}">
<ZF:DataGridNumericColumn Header="Qty" Width="80" />
</ZF:ZFDataGrid>
自定义DataGridNumericColumn运行良好,除非我第一次按下该字符。 如果我按F2进行编辑或双击该列,然后按键,一切正常。
但如果我先按键而不先编辑单元格,则自定义DataGridNumericColumn不起作用。
我把断点放在PrepareCellForEdit上,编码工作正常。但是当我按下键时,方法OnPreviewTextInput第二次工作。不是第一个。
任何人都可以给我另一种解决方案吗?
编辑:
protected override object PrepareCellForEdit(FrameworkElement editingElement, RoutedEventArgs editingEventArgs)
{
var textBox = (TextBox) editingElement;
textBox.PreviewTextInput += OnPreviewTextInput;
textBox.TextChanged += OnTextChanged; //change here
return base.PrepareCellForEdit(editingElement, editingEventArgs);
}
此代码仅运行ONCE,其余代码将由OnPreviewTextInput
处理 private void OnTextChanged(object sender, TextChangedEventArgs e)
{
var textBox = (TextBox)sender;
if (textBox.Text.Contains("-"))
{
textBox.TextChanged -= OnTextChanged;
textBox.Text = "";
}
}
答案 0 :(得分:3)
这样做比较粗糙,但我已经使用过了其他时间,它通常都能正常工作。
不是仅使用PreviewTextInput
,而是将其与TextChanged
结合使用。在第一个事件中,您只需将当前文本保存在后备字段中,然后在第二个事件中检查无效字符。如果输入了无效字符,则只需重新设置存储在字段中的上一个文本。
string oldText = string.Empty;
int oldcaret = 0;
protected override FrameworkElement GenerateEditingElement(DataGridCell cell, Object dataItem)
{
var textBox = (TextBox)base.GenerateEditingElement(cell, dataItem);
textBox.PreviewTextInput += OnPreviewTextInput;
textBox.TextChanged += OnTextChanged;
return textBox;
}
private void OnPreviewTextInput(object sender, TextCompositionEventArgs e)
{
var textBox = (TextBox)sender;
oldText = textBox.Text;
oldCaret = textBox.CaretIndex;
}
private void OnTextChanged(object sender, TextChangedEventArgs e)
{
var textBox = (TextBox)sender;
if (textBox.Text.Contains("-"))
{
textBox.Text = oldText;
textBox.CaretIndex = oldCaret;
}
}
答案 1 :(得分:1)
Instead of PrepareCellForEdit
, you could try GenerateEditingElement
:
protected override FrameworkElement GenerateEditingElement(DataGridCell cell, Object dataItem)
{
var textBox = (TextBox)base.GenerateEditingElement(cell, dataItem);
textBox.PreviewTextInput += OnPreviewTextInput;
return textBox;
}
It should be called before PrepareCellForEdit
and also before the key input is processed for the first time, I guess.