光标回归开始为什么?

时间:2013-09-27 21:44:56

标签: c# mvvm windows-phone mvvm-light

我正在制作一个有价格字段的Windows Phone应用程序。一旦用户开始输入我想要更新一些其他文本框。我正在使用mvvm light,因此通常在用户离开文本框之前不会更新该属性。

这对我来说不起作用I found this并实现它但不是我有一个奇怪的问题,我不明白为什么。

当我输入框50时,属性首先更新为“5”,然后更新为“50”,这是预期的,但是当我第一次“。”什么都没有触发,然后当我键入5时,属性似乎被击中3次,一旦完成,它将光标移回文本框的乞讨。

因此,而不是0.59,我得到90.5

背后的代码

private void txtPrice_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
    TextBox textBox = sender as TextBox;
    textBox.Text = "";
}

private void txtPrice_TextChanged(object sender, TextChangedEventArgs e)
{
    TextBox textBox = sender as TextBox;
    // Update the binding source
    BindingExpression bindingExpr = textBox.GetBindingExpression(TextBox.TextProperty);
    bindingExpr.UpdateSource();
}

在模型中

 /// <summary>
    /// The <see cref="Price" /> property's name.
    /// </summary>
    public const string PricePropertyName = "Price";

    private decimal price = 0.00M;

    /// <summary>
    /// Sets and gets the Price property.
    /// Changes to that property's value raise the PropertyChanged event. 
    /// </summary>
    public decimal Price
    {
        get
        {
            return price;
        }

        set
        {
            if (price == value)
            {
                return;
            }

            RaisePropertyChanging(() => Price);
            price = value;
            RaisePropertyChanged(() => Price);
        }
    }

XAML

<TextBox x:Name="txtPrice" Margin="157,16,102,0" TextWrapping="Wrap" VerticalAlignment="Top" InputScope="Number" Text="{Binding WeightConversion.Price, Mode=TwoWay, UpdateSourceTrigger=Explicit}" Tap="txtPrice_Tap" TextChanged="txtPrice_TextChanged" />

1 个答案:

答案 0 :(得分:2)

问题是&#34;。&#34;本身不是有效的小数,所以当绑定尝试更新价格时它失败了。进入&#34; .5&#34;它认为它是一个有效的数字,并更新Price的价值,但当价格上涨属性发生变化并转换回Text时,它会被转换为0.5,这会强制一个&#34; programmatic&#34;更新文本框并将光标重置到第一个位置。

要解决此问题,我看到的最佳解决方案可能是使用字符串属性来备份价格并更新小数值&#34;手动&#34;:

private decimal price = 0.00M;

/// <summary>
/// Sets and gets the Price property.
/// Changes to that property's value raise the PropertyChanged event. 
/// </summary>
public decimal Price
{
    get
    {
        return price;
    }

    set
    {
        if (price == value)
        {
            return;
        }

        RaisePropertyChanging(() => Price);
        price = value;
        RaisePropertyChanged(() => Price);


        this.PriceStr = this.Price.ToString();

    }
}


private string priceStr=0.00M.ToString();
/// <summary>
/// Sets and gets the Price property.
/// Changes to that property's value raise the PropertyChanged event. 
/// </summary>
public string PriceStr
{
    get
    {
        return priceStr;
    }

    set
    {
        if (priceStr == value)
        {
            return;
        }


        priceStr = value;

        isPriceAValidStr=decimal.TryParse(this.PriceStr, out price);


        RaisePropertyChanged(() => Price);
        RaisePropertyChanged(() => PriceStr);
    }
}

        private bool isPriceAValidStr = true;

并更改Text与PriceStr的绑定。

还有另一个问题,即使使用InputScope="Number",仍然有一些方法可以在文本框中输入文字:

  • 通过使用具有一个的手机的硬件键盘(在模拟器中,您可以通过按下向下翻页键来模拟它,然后您将能够使用键盘输入文本)。要解决此问题,您可以注册key_down事件并对e.Key进行一些条件检查,并通过设置e.Handled = true;拒绝您不想要的所有密钥。您也可以使用它来阻止用户输入两次.
  • 通过从另一个文本框复制一些文本,启用了文本(可能还应该删除TextChanged中的所有无效字母)