WPF,创建自定义 DataGridTextColumn 以防止不需要的字符
WPF, create Custom DataGridTextColumn to Prevent unwanted Character
我是 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);
}
此代码仅运行一次,其余由OnPreviewTextInput处理
private void OnTextChanged(object sender, TextChangedEventArgs e)
{
var textBox = (TextBox)sender;
if (textBox.Text.Contains("-"))
{
textBox.TextChanged -= OnTextChanged;
textBox.Text = "";
}
}
而不是 PrepareCellForEdit
,您可以尝试 GenerateEditingElement
:
protected override FrameworkElement GenerateEditingElement(DataGridCell cell, Object dataItem)
{
var textBox = (TextBox)base.GenerateEditingElement(cell, dataItem);
textBox.PreviewTextInput += OnPreviewTextInput;
return textBox;
}
我猜应该在 PrepareCellForEdit
之前以及第一次处理键输入之前调用它。
这是更 hackier 的方式,但我用过它其他时候,它通常工作正常。
与其仅使用 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;
}
}
我是 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);
}
此代码仅运行一次,其余由OnPreviewTextInput处理
private void OnTextChanged(object sender, TextChangedEventArgs e)
{
var textBox = (TextBox)sender;
if (textBox.Text.Contains("-"))
{
textBox.TextChanged -= OnTextChanged;
textBox.Text = "";
}
}
而不是 PrepareCellForEdit
,您可以尝试 GenerateEditingElement
:
protected override FrameworkElement GenerateEditingElement(DataGridCell cell, Object dataItem)
{
var textBox = (TextBox)base.GenerateEditingElement(cell, dataItem);
textBox.PreviewTextInput += OnPreviewTextInput;
return textBox;
}
我猜应该在 PrepareCellForEdit
之前以及第一次处理键输入之前调用它。
这是更 hackier 的方式,但我用过它其他时候,它通常工作正常。
与其仅使用 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;
}
}