3

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

2 回答 2

3

This is way hackier, but I've used it other times and it usually works fine.

Instead of using only PreviewTextInput, couple it with TextChanged too. In the first event you just save the current text in a backing field, and then in the second event you check for the invalid character. If the invalid character has been entered, you just re-set the previous text you stored in your field.

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;
    }
}
于 2015-06-27T13:17:13.010 回答
1

而不是PrepareCellForEdit,您可以尝试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.

于 2015-06-26T10:30:12.857 回答