2

We are developing a Windows Phone application (CurrencyExchange) and there is a page that includes a textbox and a listbox. ListBox's itemsource is it's viewmodel's property type of observable collection. Textbox's textchange event is changing observable collection's all items but when observable changing and trying to bind listbox's items, the page is locking. I have seen a customobservable collection named Fastobservablecollection that is not running in viewmodel because it is using DispatcherObject and Dispatcherprioty that can't use in viewmodel. Are there any alternative that better than 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);

or

 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);

Thanks.

With SmartCollection

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);
DHN
  • 4,807
  • 3
  • 31
  • 45
Tugrul Emre Atalay
  • 918
  • 1
  • 9
  • 28
  • Please add some code and how you update the Collection – Jehof Dec 04 '13 at 08:25
  • You can also take a look at [this](http://stackoverflow.com/questions/13302933/how-to-avoid-firing-observablecollection-collectionchanged-multiple-times-when-r) question if it provides useful information for you – Jehof Dec 04 '13 at 08:29
  • I have added code and I am trying your advice now – Tugrul Emre Atalay Dec 04 '13 at 08:31
  • I have tried it but no changes, still slow. Maybe I used it false. I have written last code in question, could you check it please? – Tugrul Emre Atalay Dec 04 '13 at 08:41
  • How is the type `Currency` implemented? – Jehof Dec 04 '13 at 08:53
  • Currency is our custom Class, public Double ConversionRateBuy { get; set; } public Double ConversionRateSell { get; set; } public double _calculatedValue; public Double CalculatedValue { get { return _calculatedValue; } set { SetProperty(ref _calculatedValue, value, "CalculatedValue"); } } ...... – Tugrul Emre Atalay Dec 04 '13 at 09:14

1 Answers1

2

You should not create a new SmartCollection each time, but more use only one instance and make modifications to the collection. I would suggest to change the implementation of your property CurrencyConversions to the following.

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

    return _conversions;
  }
}

Then you can call it like so in your code:

CurrencyConversions.Reset(newList);

As I currently understand your code, you are not changing (adding and removing items) the collection, but rather change the property CalculatedValue of the type Currency. When the type Currency implements the interface INotifyPropertyChanged there is no need to change the collection to update the UI, so changing your code to

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;
  }

would be enough when your type implements INotifyPropertyChanged. For that to work the property CalculatedValue should look like:

private double _value;
public double CalculatedValue{
  get{
    return _value;
  }
  set{
    _value = value;
    if (PropertyChanged != null) {
      PropertyChanged(this, new PropertyChangedEventArgs("CalculatedValue"));
    }
  }
 }
Jehof
  • 34,674
  • 10
  • 123
  • 155