WPF,创建自定义DataGridTextColumn以防止不需要的字符

时间:2015-06-26 07:37:06

标签: c# wpf datagridtextcolumn

我是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 = "";
        }
    }

2 个答案:

答案 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.