【问题标题】:Are There any better way than using ObservableCollection for fast Binding in XAML?有没有比在 XAML 中使用 ObservableCollection 进行快速绑定更好的方法?
【发布时间】:2013-12-04 21:16:00
【问题描述】:

我们正在开发一个 Windows Phone 应用程序 (CurrencyExchange),并且有一个包含文本框和列表框的页面。 ListBox 的 itemsource 是它的 viewmodel 的可观察集合的属性类型。文本框的 textchange 事件正在更改可观察集合的所有项目,但是当可观察更改并尝试绑定列表框的项目时,页面被锁定。我看到了一个名为 Fastobservablecollection 的自定义可观察集合,它没有在 viewmodel 中运行,因为它使用了不能在 viewmodel 中使用的 DispatcherObject 和 Dispatcherprioty。有没有比 ObservableCollection 更好的替代方案?

List<Currency> newList = new List<Currency>(CurrencyConversions.ToList());
foreach (var item in newList)
{
    Double result;
    if (Double.TryParse(AmountPhone, NumberStyles.Any, new System.Globalization.CultureInfo("tr-TR"), out result))
        item.CalculatedValue = Math.Round(result * (Direction == "0" ? item.ConversionRateSell : item.ConversionRateBuy), 2);
    else
        item.CalculatedValue = 0;
}
CurrencyConversions = new ObservableCollection<Currency>(newList);

 List<Currency> newList = new List<Currency>();
 foreach (var item in CurrencyConversions)
 {
     Double result;
     if (Double.TryParse(AmountPhone, NumberStyles.Any, new System.Globalization.CultureInfo("tr-TR"), out result))
         item.CalculatedValue = Math.Round(result * (Direction == "0" ? item.ConversionRateSell : item.ConversionRateBuy), 2);
     else
         item.CalculatedValue = 0;
     newList.Add(item);
 }
 CurrencyConversions = new ObservableCollection<Currency>(newList);

谢谢。

使用智能收集

List<Currency> newList = new List<Currency>(CurrencyConversions.ToList());
foreach (var item in newList)
{
    Double result;
    if (Double.TryParse(Amount, NumberStyles.Any, new System.Globalization.CultureInfo("tr-TR"), out result))
        item.CalculatedValue =Math.Round( result * (Direction == "0" ? item.ConversionRateSell : item.ConversionRateBuy),2);
    else
        item.CalculatedValue = 0;
 }
 CurrencyConversions = new SmartCollection<Currency>(newList);

【问题讨论】:

  • 请添加一些代码以及如何更新集合
  • 你也可以看看this问题,如果它为你提供了有用的信息
  • 我已经添加了代码,现在正在尝试您的建议
  • 我试过了,但没有任何变化,仍然很慢。也许我用错了。我已经写了最后一个有问题的代码,你能检查一下吗?
  • 类型Currency是如何实现的?

标签: xaml mvvm binding windows-phone observablecollection


【解决方案1】:

您不应该每次都创建一个新的SmartCollection,而更多的是只使用一个实例并对集合进行修改。我建议将您的属性CurrencyConversions 的实现更改为以下内容。

private SmartCollection<Currency> _conversions;
public SmartCollection<Currency> CurrencyConversions{
  get{
    if (_conversions == null) {
      _conversions = new SmartCollection<Currency>();
    }

    return _conversions;
  }
}

然后你可以在你的代码中这样调用它:

CurrencyConversions.Reset(newList);

据我目前了解您的代码,您不会更改(添加和删除项目)集合,而是更改CalculatedValue 类型的Currency 属性。当Currency 类型实现INotifyPropertyChanged 接口时,无需更改集合即可更新 UI,因此将代码更改为

foreach (var item in CurrencyConversions) {
  Double result;
  if (Double.TryParse(Amount, NumberStyles.Any, new System.Globalization.CultureInfo("tr-TR"), out result))
    item.CalculatedValue =Math.Round( result * (Direction == "0" ? item.ConversionRateSell : item.ConversionRateBuy),2);
  else
    item.CalculatedValue = 0;
  }

当您的类型实现 INotifyPropertyChanged 时就足够了。为此,CalculatedValue 属性应如下所示:

private double _value;
public double CalculatedValue{
  get{
    return _value;
  }
  set{
    _value = value;
    if (PropertyChanged != null) {
      PropertyChanged(this, new PropertyChangedEventArgs("CalculatedValue"));
    }
  }
 }

【讨论】:

  • 它给了我“集合已修改;枚举操作可能无法执行。” foreach 中的错误 :)
  • 我把foreach改成了for,但是速度和老一样。
  • @TuğrulEmreAtalay 我认为您的代码有问题,并且您的问题中缺少一些相关信息。我没有观察到使用 ObservableCollection 和 UI 更新的延迟或性能问题。
  • Okey @Jehof,我会尽力修复它们,感谢您的关注。
猜你喜欢
  • 2019-10-05
  • 2016-02-13
  • 2015-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-12
  • 2018-05-18
  • 2023-04-05
相关资源
最近更新 更多