-1

I have a main window with a viewmodel containing the properties:

class MainWindowModel : INotifyPropertyChanged { ObservableCollection<Currency> currencyCollection; string lastUpdated; int updateInterval; public CurrencyDataSource DataSource { get; set; } public ObservableCollection<Currency> CurrencyCollection { get { if (currencyCollection == null) currencyCollection = new ObservableCollection<Currency>(); return currencyCollection; } set { currencyCollection = value; OnPropertyChanged(); } } public string LastUpdated { get { return lastUpdated; } set { lastUpdated = value; OnPropertyChanged(); } } public int UpdateInterval { get { return updateInterval; } set { updateInterval = value; } } public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged([CallerMemberName] string propertyName="") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); if (propertyName == "LastUpdated") { System.Diagnostics.Debug.WriteLine("Property changed from main " + propertyName + " " + this.LastUpdated); } } } 

Now, all my databindings with this VM works perfect in WPF interface databindings. I also have secondary windows who are opened from main, which have the following VM:

public class CurrencyTrackModel : INotifyPropertyChanged { Currency currency; string lastUpdated; public Currency Currency { get { return currency; } set { currency = value; } } public string LastUpdated { get { return lastUpdated; } set { lastUpdated = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; void OnPropertyChanged([CallerMemberName] string propertyName = "") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); System.Diagnostics.Debug.WriteLine("Property changed from track " + propertyName + " " + this.LastUpdated); } } 

I initialize secondary windows from first as follows (I assign datacontext in constructor):

 Currency currency = (sender as Button).DataContext as Currency; CurrencyTrackModel trackModel = new CurrencyTrackModel(); trackModel.Currency = currency; trackModel.LastUpdated = model.LastUpdated; currencyTrack trackWindow = new currencyTrack(trackModel); trackWindow.Show(); 

When the properties of Currency class are updated (within main window code-behind), UI bindings in both main and secondary windows are updated perfectly. However, the property LastUpdated is only updated in the UI of main window. On further investigation, I found out that trackModel.LastUpdated does not follow mainWindow.LastUpdated; it is fixed on the first value assigned (unlike properties of Currency).

I tried to use DateTime instead of string, but it did not work as well. I have little clue how to search it on internet; reference and other searches usually result in function passing pages.

Currency class (only fields, props are standard):

 private decimal sellValue; private decimal buyValue; private decimal prevSellValue; private decimal prevBuyValue; private string sellValueColor; private string buyValueColor; private string sellArrow; private string buyArrow; 

Main window binding:

 <TextBlock Text="{Binding Path=LastUpdated,StringFormat=last Updated: {0:F}}"></TextBlock> 

Secondary window binding:

<TextBlock Text="{Binding Path=LastUpdated, StringFormat=f}"></TextBlock> 
2
  • I think the issue is with the repaint not being called in the window. I have seen in many cases when a DGV datasource is a datatable and the table gets updated but not the DGV. The trick in solving issue is to set the DataSource to null and then to the datatable. Commented Dec 10, 2016 at 13:15
  • I think the problem is not in UI; the databound value underneath the second property is not synced with the first. I.e. when I say trackModel.LastUpdated = model.LastUpdated;, trackmodel and model have somehow different objects, whereas it should be they are pointing to the same object. Moreover, WPF interfaces are usually specialized for databinding so they do not have issues in repainting. Commented Dec 10, 2016 at 14:24

1 Answer 1

1

However, the property LastUpdated is only updated in the UI of main window.

This is because the second window is bound to a completely different source property than the MainWindow and updating the source property of the MainWindowModel class will not automatically update the source property of the CurrencyTrackModel.

DateTime is a value type so the following code line simply creates a copy of the DateTime value and assign it to the LastUpdated property of the CurrencyTrackModel:

trackModel.LastUpdated = model.LastUpdated; 

After this there is no form of connection between the LastUpdated property of the MainViewModel and the LastUpdate property of the CurrencyTrackModel. You will have two different DateTime objects in memory and one of the properties will not affect the other one.

You will have to set the LastUpdated property of the CurrencyTrackModel whenever you want the TextBlock in the second window to be updated. Alternatively you could use the same view model for both windows and bind both TextBlocks to the very same source property.

Sign up to request clarification or add additional context in comments.

3 Comments

Actually first I used DateTime, and then I realized it is a value type so I converted LastUpdated property to string, thinking strings are reference type. By this way, I thought main and currency window data sources will point to the same object but apparently they do not.
No, they don't because strings are also immutable so it will work the same way as with DateTime. It's true that System.String is indeed a reference type but it still behaves as a value type: stackoverflow.com/questions/2911712/…
Well that makes a lot of sense. Thanks.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.