0

DataGrid への列用にこの XAML があります

<DataGridTemplateColumn Header="% Deduccion Anticipo">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding NumPorcentajeAnticipo, Mode=TwoWay, StringFormat={}{0:00.}%}" Visibility="{Binding Merlin_ConceptosFacturacion.BitOtrosItms_Anticipos,Converter={StaticResource boolToVisibility}}"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <TextBox Text="{Binding NumPorcentajeAnticipo, Mode=TwoWay,StringFormat={}{0:00.}%}" Visibility="{Binding Merlin_ConceptosFacturacion.BitOtrosItms_Anticipos,Converter={StaticResource boolToVisibility}}"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

Stringformat は期待どおりに適用されますが、多くの問題は、ユーザーが任意の char alpha、number symbol を入力できることです。それを防ぐにはどうすればよいですか?入力マスクを設定することは可能ですか?

私は別の StringFormats を試していましたが、どれも期待どおりに機能します。

更新: 列は現在、ビュー モデルの Numeric プロパティにバインドされています。

4

4 に答える 4

1

のKeyDownイベントを使用して、TextBox無効な値をインターセプトして除外できます。カプセル化されたソリューションを改善するために、独自の派生TextBoxおよびオーバーライドを作成することもできます。OnKeyDown

于 2013-09-27T17:46:03.670 に答える
0

次の方法を使用して、要件を達成できます。

  1. マスクされたテキスト ボックスを CellEditingTemplate に配置し、そのマスクされたテキスト ボックスにマスクを設定します。
  2. 要件に基づいてカスタム レンダリングを作成し、CellEditingTemplate にバインドします。
于 2013-09-28T03:52:15.550 に答える
0

いくつかの調査の後、別の質問でこれが見つかりました:

WPF での数値データ入力および@Brian Hinchey の回答は、私のニーズの一部と一致します。

10 進数のカルチャ検証と、編集および検証ツールを自分で追加するだけです。これが他の誰かを助けることを願っています。

使用するには:

<DataGridTemplateColumn.CellEditingTemplate>
   <DataTemplate>
      <controls:NumericTextBox DecimalPlaces="2" DecimalSeparator="."/>
   </DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>

小数点以下の桁数または区切り記号が指定されていない場合は、CultureInfo.CurrentCultureparmsが使用されます

最終的なコードは次のとおりです。

public class NumericTextBox : TextBox
{
    #region Formato
    private string previousText = "";
    private bool ApplyingFormat = false;
    private CultureInfo _CI = new CultureInfo(CultureInfo.CurrentCulture.LCID,true);
    public CultureInfo CI
    {
        get { return _CI; }
        set { _CI = value; }
    }

    private int _DecimalPlaces = 0;
    /// <summary>
    /// Numero de plazas decimales 
    /// </summary>
    public int DecimalPlaces
    {
        get { return _DecimalPlaces; }
        set { _DecimalPlaces = value; _CI.NumberFormat.NumberDecimalDigits = value; }
    }
    public Decimal DecimalValue = 0;

    private string _DecimalSeparator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
    public string DecimalSeparator
    {
        get { return _DecimalSeparator; }
        set { _DecimalSeparator = value; _CI.NumberFormat.NumberDecimalSeparator = _DecimalSeparator; }
    }

    //public string DecimalSeparator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
    #endregion 


    public NumericTextBox()
    {
        HorizontalContentAlignment = HorizontalAlignment.Right;
        DataObject.AddPastingHandler(this, OnPaste);
    }

    private void OnPaste(object sender, DataObjectPastingEventArgs dataObjectPastingEventArgs)
    {
        var isText = dataObjectPastingEventArgs.SourceDataObject.GetDataPresent(System.Windows.DataFormats.Text, true);
        if (isText)
        {
            var text = dataObjectPastingEventArgs.SourceDataObject.GetData(DataFormats.Text) as string;
            if (IsTextValid(text))
            {
                return;
            }
        }
        dataObjectPastingEventArgs.CancelCommand();
    }

    private bool IsTextValid(string enteredText)
    {
        //  If keyboard insert key is in toggled mode, and the actual insert point is Decimalseparator, we must avoid to overwrite it
        if (SelectionStart == this.Text.IndexOf(DecimalSeparator)
            & System.Windows.Input.Keyboard.GetKeyStates(System.Windows.Input.Key.Insert) == System.Windows.Input.KeyStates.Toggled)
        {
            SelectionStart += 1;
        }

        if (!enteredText.All(c => Char.IsNumber(c) || c == DecimalSeparator.ToCharArray()[0] || c == '-'))
        {
            return false;
        }

        //We only validation against unselected text since the selected text will be replaced by the entered text
        var unselectedText = this.Text.Remove(SelectionStart, SelectionLength);
        if ( enteredText == DecimalSeparator && unselectedText.Contains(DecimalSeparator))
        {
            //  Before return false, must move cursor beside Decimal separator
            SelectionStart = this.Text.IndexOf(DecimalSeparator) + 1;
            return false;
        }

        if (enteredText == "-" && unselectedText.Length > 0)
        {
            return false;
        }

        return true;
    }

    private bool ApplyFormat(TextChangedEventArgs e)
    {
        if (!ApplyingFormat)
        {
            ApplyingFormat = true;
            int SelectionStartActual = SelectionStart;
            string FinallText = this.Text;
            if (!FinallText.Contains(DecimalSeparator) & DecimalPlaces > 0)
            {
                FinallText = String.Format("{0}{1}{2}", this.Text, DecimalSeparator, new string('0', DecimalPlaces));
            }
            bool state = Decimal.TryParse(FinallText, NumberStyles.AllowCurrencySymbol | NumberStyles.AllowDecimalPoint | NumberStyles.AllowTrailingSign, _CI, out DecimalValue);
            DecimalValue = Math.Round(DecimalValue, DecimalPlaces);
            if (DecimalValue == 0)
            {
                FinallText = "";
            }
            else
            {
                if (FinallText != DecimalValue.ToString(_CI))
                {
                    FinallText = DecimalValue.ToString(_CI);
                }
            }
            if (FinallText != this.Text)
            {
                this.Text = FinallText;
                SelectionStart = SelectionStartActual;
            }

            previousText = this.Text;

            ApplyingFormat = false;
            return state;
        }
        else
        {
            return true;
        }
    }

    protected override void OnTextChanged(TextChangedEventArgs e)
    {
        e.Handled = !ApplyFormat(e);
        base.OnTextChanged(e);
    }

    protected override void OnPreviewTextInput(System.Windows.Input.TextCompositionEventArgs e)
    {
        e.Handled = !IsTextValid(e.Text);
        base.OnPreviewTextInput(e);
    }
}
于 2013-09-29T20:27:26.197 に答える