【问题标题】:Bound TextBox does not update绑定的文本框不更新
【发布时间】:2014-02-04 19:04:51
【问题描述】:

我有一个绑定到 ObservableCollection 对象(具有多个属性)的 ComboBox。组合框准确地显示所有对象的所需属性,我可以按预期从组合中选择任何项目。

<ComboBox Height="23" Name="comboBox1" Width="120" Margin="5" ItemsSource="{Binding Issues}" DisplayMemberPath="Issue" SelectedValuePath="Issue" SelectedValue="{Binding Path=Issues}" IsEditable="False" SelectionChanged="comboBox1_SelectionChanged" LostFocus="comboBox1_LostFocus" KeyUp="comboBox1_KeyUp" Loaded="comboBox1_Loaded" DropDownClosed="comboBox1_DropDownClosed" IsSynchronizedWithCurrentItem="True" />

我有一系列文本框,它们应该显示所选对象的其他属性。这也很好用。

<TextBox Height="23" Name="textBox5" Width="59" IsReadOnly="True" Text="{Binding Issues/LastSale, StringFormat={}{0:N4}}" />
<TextBox Height="23" Name="textBox9" Width="90" IsReadOnly="True" Text="{Binding Path=Issues/LastUpdate, Converter={StaticResource TimeConverter}}" />

但是... ObservableCollection 的属性会定期在 Code-Behind 中更新,并且每次更新属性时,我都会通过在其中添加或删除一个虚拟对象来更改 OC。 (我发现这比其他解决方案更简单)。

但是...文本框中的数据不会改变! :-( 如果我从 ComboBox 中选择不同的对象,我会得到更新的信息,但在更改 OC 时它不会更改。

OC 是由一堆这样的 Objects 组成的:

public class IssuesItems
{
  public String Issue { get; set; }
  public Double LastSale { get; set; }
  public DateTime LastUpdate { get; set; }
  ...
 }

OC定义为:

public ObservableCollection<IssuesItems> Issues { get; set; }

并实例化:

this.Issues = new ObservableCollection<IssuesItems>();

我做错了什么?我读到的所有内容都表明,当 OC 中的 LastSale 和 LastUpdate 属性发生变化时(并且我做了一些事情来强制更新 OC),文本框中的数据应该会发生变化。

【问题讨论】:

  • 每次ObservableCollection 更新时,您是否都在引发propertychanged 事件?

标签: c# wpf data-binding combobox observablecollection


【解决方案1】:

ObservableCollection 实现了INotifyCollectionChanged,它允许在集合中添加或删除任何项目时刷新 GUI(您不必担心手动操作)。

但就像我提到的那样,这仅限于从集合中添加/删除项目,但是 如果您希望在任何基础属性发生更改时刷新 GUI,您的基础源类必须实现 INotifyPropertyChanged 以向 GUI 通知属性已更改,因此请刷新自己。

IssuesItems 应该在你的情况下实现 INPC 接口。

请参阅此 - How to implement INotifyPropertyChanged on class

  public class IssuesItems : INotifyPropertyChanged
  {
      private string issue;
      public string Issue
      {
          get { return issue; }
          set
          {
              if(issue != value)
              {
                 issue= value;
                 // Call OnPropertyChanged whenever the property is updated
                 OnPropertyChanged("Issue");
              }
          }
      }

      // Declare the event 
      public event PropertyChangedEventHandler PropertyChanged;
      // Create the OnPropertyChanged method to raise the event 
      protected void OnPropertyChanged(string name)
      {
          PropertyChangedEventHandler handler = PropertyChanged;
          if (handler != null)
          {
              handler(this, new PropertyChangedEventArgs(name));
          }
      }
  }

实现其他属性,就像上面提到的Issue

【讨论】:

  • 每次更改一批属性后,我都会执行 add() 或 RemoveAt() 。我认为这会触发内置的 OC 事件,正如你上面所说的。但!!我觉得我懂了!我的添加/删除导致 IssueItems (集合)的列表被更新,但不是预先存在的项目的值。是对的吗?如果我用包含新数据的新项目替换了旧项目,那么我的添加/删除操作就可以了。
  • 是的,就是这样!谢谢!
猜你喜欢
  • 2011-09-22
  • 2015-05-16
  • 2023-04-04
  • 2017-03-18
  • 1970-01-01
  • 2016-04-20
  • 2012-08-14
  • 1970-01-01
  • 2015-10-21
相关资源
最近更新 更多