Silverlight 中的十进制转换器无法正确处理丢失焦点

Posted

技术标签:

【中文标题】Silverlight 中的十进制转换器无法正确处理丢失焦点【英文标题】:Decimal Converter in Silverlight is not working on Lost Focus properly 【发布时间】:2012-08-22 12:18:28 【问题描述】:

我正在使用 Silverlight 中的绑定。我已将 TextBox 与 Decimal 实体绑定。 下面是绑定的代码片段。

以下是转换器代码。

    decimal result;
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
                
        if (!Decimal.TryParse(value.ToString(),out result) || (decimal)value == decimal.Zero)
            return null;
        return decimal.Parse(value.ToString());
    

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    
        if (value == null || !Decimal.TryParse(value.ToString(), out result))
            return 0.00;
        return decimal.Parse(value.ToString());
    

关于失去焦点,我正在更新源 和 GetBindingExpression(TextBox.TextProperty).UpdateSource();

一切都很好,但是当我在文本框中输入字符串时,不会调用转换,当我在文本框中输入字符串时,不会调用转换,它不会将文本框文本转换为空白。

谁能给我建议,代码中的问题是什么。

提前致谢。 ----拉杰

【问题讨论】:

【参考方案1】:

TwoWay 模式绑定TextChangedLostFocus 事件绝对不是最好的方法。如果默认绑定,为什么在LostFocus 中调用GetBindingExpression(TextBox.TextProperty).UpdateSource();?如果要手动更新绑定,请设置UpdateSourceTrigger=Explicit

无论如何,您的转换器看起来不错,但我认为您不需要它。如果我理解正确,如果无法将文本转换为十进制,则要清除文本。在这种情况下,您有几个选项,例如创建只允许数字的自定义TextBox,或者您可以检查Silverlight Toolkit 中的NumericUpDown 控件。我也发现了类似的问题here。

如果你已经安装了Microsoft Expression Blend(如果没有,你可以从Microsoft Expression Blend Software Development Kit下载BlendSLSDK_en.msi),添加System.Windows.Interactivity dll到你的项目中,然后像这样创建简单的Behavior

public class TextBoxClearTextBehavior : System.Windows.Interactivity.Behavior<System.Windows.Controls.TextBox>

    protected override void OnAttached()
    
        AssociatedObject.LostFocus += AssociatedObjectLostFocus;
        base.OnAttached();
    

    protected override void OnDetaching()
    
        AssociatedObject.LostFocus -= AssociatedObjectLostFocus;
        base.OnDetaching();
    

    private void AssociatedObjectLostFocus(object sender, System.Windows.RoutedEventArgs e)
    
        decimal result;
        if (!decimal.TryParse(AssociatedObject.Text, out result))
            AssociatedObject.Text = string.Empty;
    

并像使用它

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

...    

<TextBox Text="Binding Amount, Mode=TwoWay, StringFormat=\0:n2\">
    <i:Interaction.Behaviors>
        <Behavior:TextBoxClearTextBehavior/>
    </i:Interaction.Behaviors>
</TextBox>

【讨论】:

谢谢...当我在 TextBox 中输入字符串时,我认为 Bindings 会出现异常,因为我将它绑定到十进制值。所以转换器没有被调用。 @user1173233,应该没有异常,你可以在输出窗口中查看。在您向TextBox 输入值后调用ConvertBack 方法并返回Decimal。 谢谢..我认为你是对的,但不知道为什么没有调用转换【参考方案2】:

根据您的描述,“在失去焦点时不会调用转换,当我在文本框中输入字符串时,不会调用转换,它不会将文本框文本转换为空白。”

这里,Convert 方法只会在与 TextBox 的 Text 属性的绑定发生变化时调用。由于您提到了 Mode=TwoWay 进行绑定,因此当您在文本框中输入任何文本时,将调用 ConvertBack 方法,并且从此方法返回的值将分配给 Source,在您的情况下,是 SelectedEntity.Amount。

我不明白为什么我们需要显式编写 GetBindingExpression(TextBox.TextProperty).UpdateSource();失去焦点的代码更新源代码。

理想情况下,由于您保留了绑定模式两种方式,它应该在调用 Converter 的 ConvertBack 方法后更新源。 转换器代码在我看来没问题。

如果您需要更多详细信息,或者我可能误解了某些内容,请告诉我。

【讨论】:

我认为当我在 TextBox 中输入字符串时,Bindings 会出现异常,因为我将它绑定到十进制值。所以转换器没有被调用。【参考方案3】:

如果您手动更新 TextChanged 事件中的绑定,如下所示:

GetBindingExpression(TextBox.TextProperty).UpdateSource();

也许您在 LostFocus 事件中获得的值与您在 TextChanged 事件中更新的值不会不同!

所以,很可能转换器不会被调用,只是因为绑定中的值没有改变!

希望这会有所帮助!

【讨论】:

我认为当我在 TextBox 中输入字符串时,Bindings 会出现异常,因为我将它绑定到十进制值。所以转换器没有被调用。

以上是关于Silverlight 中的十进制转换器无法正确处理丢失焦点的主要内容,如果未能解决你的问题,请参考以下文章

Silverlight 4中的IIS Windows身份验证问题

代码转换 swift 2 --> 3 导致索引路径处的二进制运算符错误

在 Windows Phone 和 Silverlight 中将 Image Feed 转换为 BitmapImage

将 wav 文件转换为没有标头的原始二进制文件

Silverlight/WPF 用十六进制颜色设置椭圆

我无法从Silverlight业务应用程序中的代码中获取查询结果