【问题标题】:WPF binding not working properly with properties of int typeWPF 绑定无法与 int 类型的属性一起正常工作
【发布时间】: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 等数据绑定属性。

标签: c# wpf silverlight xaml data-binding


【解决方案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。虽然我认为首选方法是类型转换器而不是重复属性。
      • 谢谢。我只是问,以防我错过了什么。建设性的批评总是受欢迎的,因为我们还能从错误中学到什么?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-27
      • 1970-01-01
      • 2016-09-06
      • 1970-01-01
      • 2023-04-05
      • 2019-10-31
      • 1970-01-01
      相关资源
      最近更新 更多