WPF 绑定无法与 int 类型的属性一起正常工作

Posted

技术标签:

【中文标题】WPF 绑定无法与 int 类型的属性一起正常工作【英文标题】:WPF binding not working properly with properties of int type 【发布时间】:2010-11-15 00:14:28 【问题描述】:

我的视图模型中有一个int 类型的属性,它绑定到TextBox。一切正常,TwoWay 绑定工作正常,但在一种情况下 -

如果我清除了TextBox 的值,则不会调用属性设置器,尽管在TextBox 中清除了值,但属性仍保留以前的值。

有没有人遇到过类似的问题?有什么解决方法吗?

这里是属性 -

public int MaxOccurrences

    get
    
        return this.maxOccurrences;
    
    set
    
        if (this.maxOccurrences != value)
        
            this.maxOccurrences = value;
            base.RaisePropertyChanged("MaxOccurrences");
        
    

这是我在 xaml 中绑定属性的方式 -

<TextBox Text="Binding Path=MaxOccurrences, Mode=TwoWay, 
    NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged" 
    HorizontalAlignment="Center" Width="30" Margin="0,0,5,0"/>

【问题讨论】:

我很想知道这种行为在 Silverlight 中是否相同?任何人! Silverlight 中的行为相同,但 Silverlight 中不支持 NotifyOnSourceUpdated 和 UpdateSourceTrigger 等数据绑定属性。 【参考方案1】:

我也遇到过类似的问题。

您只需将代码更新为:

<TextBox Text="Binding Path=MaxOccurrences, Mode=TwoWay, TargetNullValue=x:Static sys:String.Empty,
NotifyOnSourceUpdated=True,  UpdateSourceTrigger=PropertyChanged"  
HorizontalAlignment="Center" Width="30" Margin="0,0,5,0"/> 

【讨论】:

xmlns:sys="clr-namespace:System;assembly=mscorlib" .net 3.5 或更高版本,请尝试TargetNullValue=''【参考方案2】:

如果您不想使用Nullableinteger,可以使用将空的string 转换为0 的converter,请参见下面的代码:

public class EmptyStringToZeroConverter : IValueConverter

    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    
        return value;
    

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    
        return value == null || string.IsNullOrEmpty(value.ToString())
            ? 0
            : value;
    

    #endregion

【讨论】:

感谢 Mohammed,但一年前“Simon”已经提到了这个解决方案。 为了搜索者的利益,我发现这个值转换器 (codecisions.com/…) 保持文本框显示为空,而不是像这个答案似乎在前景中将其更改为零。显然取决于你的要求。【参考方案3】:

这部分是猜测(我现在没有 VS 方便试用),但我认为这是因为清除的文本框是空的 string (""),这不可能隐式转换为int。您可能应该实现一个类型转换器来为您提供转换。 (您可能想做一些类似将“”转换为 0)

【讨论】:

最简单的检查方法——在 Visual Studio 中运行项目并观察输出窗口(查看-输出)。清除文本框后,您应该会看到 Simon 所说的绑定错误。【参考方案4】:

Akjoshi,我有一个可行的解决方案!

您需要将整数属性更改为Naullable&lt;int&gt;(即int?),请参见以下sn-p:

private int? _maxOccurrences;
public int? MaxOccurrences

    get  return _maxOccurrences; 
    set  _maxOccurrences = value; 

还需要添加一个值转换器来将空字符串转换为空值,见以下代码sn-p:

public class EmptyStringToNullConverter : IValueConverter

    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    
        return value;
    

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    
        return value == null || string.IsNullOrEmpty(value.ToString())
            ? null
            : value;
    

    #endregion

XAML 代码:

<Window x:Class="ProgGridSelection.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:System="clr-namespace:System;assembly=mscorlib" 
    xmlns:local="clr-namespace:ProgGridSelection"
    Title="MainWindow"
    Height="136" Width="525"
    Loaded="OnWindowLoaded">
<Window.Resources>
    <local:EmptyStringToNullConverter x:Key="EmptyStringToNullConverter"/>
</Window.Resources>
<StackPanel>
    <Button Content="Using Empty String to Null Converter"/>
    <TextBox Name="empNameTextBox"
             Text="Binding Mode=TwoWay, Path=MaxOccurrences,
                RelativeSource=RelativeSource FindAncestor, AncestorType=Window,
                Converter=StaticResource EmptyStringToNullConverter"/>
</StackPanel>

[注意:这只是一个概念证明,为了简单起见,我没有使用任何模式或最佳实践]

【讨论】:

【参考方案5】:

我有同样的问题,但我需要处理而不是数值。为此,我使用以下转换器:

public class StringFormatToIntConverter : IValueConverter
            
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    
          return value.ToString();
    

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    
       if(value is string)
       
           var inttext = 
            System.Text.RegularExpressions.Regex.Replace((string)value, "[^.0-9]", "");

           int number;
           return Int32.TryParse(inttext, out  number) ? number : 0;
       
       else
       
           return value;
       
    

【讨论】:

【参考方案6】:

这是因为int 值不能是null。 最好使用 string 属性,它将代码中的值转换为所需的 int 属性字段。

这样你就可以执行一个

if(string.IsNullOrEmpty(text))

  this.intValue = 0;

【讨论】:

我看不出有什么问题。给我一个+1。虽然我认为首选方法是类型转换器而不是重复属性。 谢谢。我只是问,以防我错过了什么。建设性的批评总是受欢迎的,因为我们还能从错误中学到什么?

以上是关于WPF 绑定无法与 int 类型的属性一起正常工作的主要内容,如果未能解决你的问题,请参考以下文章

无法数据绑定滑块 WPF 的值 [重复]

如何在C#中将列表与WPF数据网格绑定?

数据绑定到 WPF 中的 UserControl

与底部相关的 AlertDialog 属性无法与 RelativeLayout 或 ConstraintLayout 一起正常工作

WPF自定义控件数据绑定出现的问题

WPF学习第二十九章 元素绑定——将元素绑定到一起