Properly display dynamic calculations in databinding? [modified]
-
You really need to call NotifyPropertyChanged (hint - you should implement INotifyPropertyChanged on any datasource that you don't intend to use OneWay binding on).
Deja View - the feeling that you've seen this post before.
I've tried doing that but nothing has changed. I used the example from INotifyPropertyChanged on MSDN for a template. Here is a snippet of my code: public class SubtitleItem : IComparable, INotifyPropertyChanged { private TimeSpan _TimeCodeStart; public TimeSpan TimeCodeStart { get { return _TimeCodeStart; } set { if (_TimeCodeStart != value) { _TimeCodeStart = value; NotifyPropertyChanged("TimeCodeStart"); } } } private TimeSpan _TimeCodeEnd; public TimeSpan TimeCodeEnd { get { return _TimeCodeEnd; } set { if (_TimeCodeEnd != value) { _TimeCodeEnd = value; NotifyPropertyChanged("TimeCodeEnd"); } } } public TimeSpan TimeCodeDuration { get { return TimeCodeEnd - TimeCodeStart; } } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String info) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(info)); } } } What am I missing?
modified on Wednesday, April 30, 2008 7:00 PM
-
I've tried doing that but nothing has changed. I used the example from INotifyPropertyChanged on MSDN for a template. Here is a snippet of my code: public class SubtitleItem : IComparable, INotifyPropertyChanged { private TimeSpan _TimeCodeStart; public TimeSpan TimeCodeStart { get { return _TimeCodeStart; } set { if (_TimeCodeStart != value) { _TimeCodeStart = value; NotifyPropertyChanged("TimeCodeStart"); } } } private TimeSpan _TimeCodeEnd; public TimeSpan TimeCodeEnd { get { return _TimeCodeEnd; } set { if (_TimeCodeEnd != value) { _TimeCodeEnd = value; NotifyPropertyChanged("TimeCodeEnd"); } } } public TimeSpan TimeCodeDuration { get { return TimeCodeEnd - TimeCodeStart; } } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String info) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(info)); } } } What am I missing?
modified on Wednesday, April 30, 2008 7:00 PM
Can you please post the XAML so we can see what you are doing in that code.
Cheers, Karl
» CodeProject 2008 MVP » Microsoft MVP - Client App Dev My Blog | Mole's Home Page | MVP ProfileJust a grain of sand on the worlds beaches.
-
Can you please post the XAML so we can see what you are doing in that code.
Cheers, Karl
» CodeProject 2008 MVP » Microsoft MVP - Client App Dev My Blog | Mole's Home Page | MVP ProfileJust a grain of sand on the worlds beaches.
Karl, the entire project (only like 6 major files) is online here: http://subhub.svn.sourceforge.net/viewvc/subhub/trunk/SubHubWpf/[^] I've also created a test project that is extremely lean that reproduces the problem. It's here: http://www.crankedup.com/misc/wpf-databinding-calcupdate.zip[^]
-
Karl, the entire project (only like 6 major files) is online here: http://subhub.svn.sourceforge.net/viewvc/subhub/trunk/SubHubWpf/[^] I've also created a test project that is extremely lean that reproduces the problem. It's here: http://www.crankedup.com/misc/wpf-databinding-calcupdate.zip[^]
Give this minor tweek a go:
private TimeSpan _TimeCode;
public TimeSpan TimeCode
{
get { return _TimeCode; }
set
{
_TimeCode = value;
NotifyPropertyChanged("TimeCode");
NotifyPropertyChanged("TimeCodeCalc");
}
}Since TimeCodeCalc is ready only, you just need to tell the UI that it changed. Presto, you are in business.
Cheers, Karl
» CodeProject 2008 MVP » Microsoft MVP - Client App Dev My Blog | Mole's Home Page | MVP ProfileJust a grain of sand on the worlds beaches.
-
Give this minor tweek a go:
private TimeSpan _TimeCode;
public TimeSpan TimeCode
{
get { return _TimeCode; }
set
{
_TimeCode = value;
NotifyPropertyChanged("TimeCode");
NotifyPropertyChanged("TimeCodeCalc");
}
}Since TimeCodeCalc is ready only, you just need to tell the UI that it changed. Presto, you are in business.
Cheers, Karl
» CodeProject 2008 MVP » Microsoft MVP - Client App Dev My Blog | Mole's Home Page | MVP ProfileJust a grain of sand on the worlds beaches.
Thanks, that's working. I guess I misunderstood how this process worked. I thought you informed the system of what changed then it would automagically know that the whole object had changed and needed to be updated. But the way it actually seems to work looks like there are plenty of ways for bugs to creep in. For instance, in my real project, the property IsModified will have to be notified from every field that can be changed. Are there any solutions to just hardcoding a bunch of these NotifyPropertyChanged in every editable field?
-
Thanks, that's working. I guess I misunderstood how this process worked. I thought you informed the system of what changed then it would automagically know that the whole object had changed and needed to be updated. But the way it actually seems to work looks like there are plenty of ways for bugs to creep in. For instance, in my real project, the property IsModified will have to be notified from every field that can be changed. Are there any solutions to just hardcoding a bunch of these NotifyPropertyChanged in every editable field?
If you have a field that changes anytime other properties are changed, you can raise that event in the PropertyChanged method. INotifyPropertyChanged interface just notifies the UI when an individual property is changed. This is currently the standard method for property change notification. Another option you have is to create an object that has Dependency Properties. These have all the plumbing built in for change notification. Have a look at my article: http://www.codeproject.com/KB/WPF/WPFBusinessAppsPartThree.aspx[^] Go look how I did the time display control. It also has a read only property that changes every 60 seconds and notifies the UI. There are plenty of articles here on Code Project on writing your own Dependency Properties if you want to go that route.
Cheers, Karl
» CodeProject 2008 MVP » Microsoft MVP - Client App Dev My Blog | Mole's Home Page | MVP ProfileJust a grain of sand on the worlds beaches.
-
If you have a field that changes anytime other properties are changed, you can raise that event in the PropertyChanged method. INotifyPropertyChanged interface just notifies the UI when an individual property is changed. This is currently the standard method for property change notification. Another option you have is to create an object that has Dependency Properties. These have all the plumbing built in for change notification. Have a look at my article: http://www.codeproject.com/KB/WPF/WPFBusinessAppsPartThree.aspx[^] Go look how I did the time display control. It also has a read only property that changes every 60 seconds and notifies the UI. There are plenty of articles here on Code Project on writing your own Dependency Properties if you want to go that route.
Cheers, Karl
» CodeProject 2008 MVP » Microsoft MVP - Client App Dev My Blog | Mole's Home Page | MVP ProfileJust a grain of sand on the worlds beaches.
OK, thanks. I'll give that sample a look and read up more about dependency properties.
-
Give this minor tweek a go:
private TimeSpan _TimeCode;
public TimeSpan TimeCode
{
get { return _TimeCode; }
set
{
_TimeCode = value;
NotifyPropertyChanged("TimeCode");
NotifyPropertyChanged("TimeCodeCalc");
}
}Since TimeCodeCalc is ready only, you just need to tell the UI that it changed. Presto, you are in business.
Cheers, Karl
» CodeProject 2008 MVP » Microsoft MVP - Client App Dev My Blog | Mole's Home Page | MVP ProfileJust a grain of sand on the worlds beaches.
Karl, I have another question now. Based on editing one subitem, I need to change a value in another subitem. The change is working but the other subitem is not reflecting it's new value in the list. I've implemented INotifyPropertyChanged on both the Item and Subitem classes but am unsure how to tell Wpf that other items in the list need to updated. Nevermind, I think I've found the problem. I really need to get into those dependency properties because this INotifyPropertyChanged is turning into spaghetti.
modified on Thursday, May 1, 2008 6:12 PM
-
Karl, I have another question now. Based on editing one subitem, I need to change a value in another subitem. The change is working but the other subitem is not reflecting it's new value in the list. I've implemented INotifyPropertyChanged on both the Item and Subitem classes but am unsure how to tell Wpf that other items in the list need to updated. Nevermind, I think I've found the problem. I really need to get into those dependency properties because this INotifyPropertyChanged is turning into spaghetti.
modified on Thursday, May 1, 2008 6:12 PM
artwallacex wrote:
this INotifyPropertyChanged is turning into spaghetti
INotifyProperyChanged should not be causing you too much grief. This is a very standard interface used by most WPF business objects that are bound to the UI. If I could offer a suggestion? This is what I do when things get out of hand. Write a very simple version of what you are trying to accomplish and work it piece by piece. The answer will come. If it doesn't, then you have a very simple project that anyone can look at and provide assistance. Trust me, I've been there. :cool: Have a super day!
Cheers, Karl
» CodeProject 2008 MVP » Microsoft MVP - Client App Dev My Blog | Mole's Home Page | MVP ProfileJust a grain of sand on the worlds beaches.
-
Thanks, that's working. I guess I misunderstood how this process worked. I thought you informed the system of what changed then it would automagically know that the whole object had changed and needed to be updated. But the way it actually seems to work looks like there are plenty of ways for bugs to creep in. For instance, in my real project, the property IsModified will have to be notified from every field that can be changed. Are there any solutions to just hardcoding a bunch of these NotifyPropertyChanged in every editable field?
artwallacex wrote:
Are there any solutions to just hardcoding a bunch of these NotifyPropertyChanged in every editable field?
Since you're using WPF then you'll be using C# 2.0 at least so you could do something like this (just made up an example since I haven't downloaded your files):
private TimeSpan _TimeCode;
private TimeSpan _TimeCodeCalc;public TimeSpan TimeCode
{
get { return _TimeCode; }
set
{
_TimeCode = value;
TimeCodeCalc = new TimeSpan(value.TotalMinutes); // Change another "readonly" property
NotifyPropertyChanged("TimeCode");
}
}
public TimeSpan TimeCodeCalc
{
get { return _TimeCodeCalc; }
private set
{
_TimeCodeCalc = value;
NotifyPropertyChanged("TimeCodeCalc");
}
}You'll notice the
private
modifier on theTimeCodeCalc
property, what this does is that only your class will be able to change the value. If you wrap your readonly properties like this then at least when you modify them you only have to set the wrapper property and thePropertyChanged
event will be fired off. That way you don't have to remember to fire notify about every property in every place where you set it. Just use the newprivate set
method rather than the field to modify the value. [edit] I've had a look at your simple solution and modified it to give you an example: http://www.pooredesign.com/downloads/wpf-databinding-calcupdate.zip[^] [/edit]