Hi,
I have a form with 40 databound controls. The controls (mostly TextBoxes etc.) are connected to data model that implements INotifyPropertyChanged. The problem we face is that each control is pushed data when a single data model property changes. This is a significant problem during initialization when all the properties are set, causing 40 x 40 =1600 getter calls, but it's a problem in normal property usage, too, if some properties must be fetched from database instead of private member.
I have tried to counter this problem by using some block operations that internally do not use properties, but private members etc. This doesn't really work anymore because I need to use robust and simple interface from now on without these optimized block operations.
Is there any way to use DataBinding with INotifyPropertyChanged without this overhead of redundant getter calls
-Kimmo

Horrible databinding performance
bharath-k
Not sure I understand the problem. A few questions, if you don't mind:
1. Why is it that "each control is pushed data when a single data model property changes" For example, if a single textbox control is bound to a single property, then when that property changes, the data would only get pushed to that single control and no other controls would be involved, correct
2. What is happening during initialization, that the 40 controls get initialized 40 times each
3. As each property is changed, you raise the PropertyChanged event specifying the sepcific (and only the specific) property that changed, correct
Almost sounds like you are raising PropertyChanged but NOT specifying any property, which is the equivalent of indicating that ALL properties have changed. For example doing something like:
RaiseEvent
PropertyChanged(Me, New PropertyChangedEventArgs(""))instead of
RaiseEvent
PropertyChanged(Me, New PropertyChangedEventArgs("PropertyName"))papercodes
Kimmock:
What do you make of this in the product feedback center
https://connect.microsoft.com/feedback/viewfeedback.aspx FeedbackID=115342&wa=wsignin1.0&siteid=210
Seems contrary to our wishes.
DRCH
Interesting. I tried to reproduce that problem and it's related to BindingSource somehow. If I bind the properties of datamodel directly to GUI controls (without BindingSource), the problem disappears.
In any case, I hope Microsoft fixes both problems. If someone really wanted all the controls to be refreshed when a single property changes, he could just simply call PushData. But for our problem (all inrelevant controls are pushed data) there is no general workaround to my knowledge.
-Kimmo
cgrinton
It appears that everything you are doing is correct, at least in my limited experience opinion. And I have replicated the problem you are referring to and I am a little surprised. Also, I have noticed that when I bind the GetterCount to the label, the label gets updated even though I do not raise the PropertyChanged event in the GetterCount property setter of my sample appllication - this suggests that it is being updated from somewhere else other than the Person object (most likley something to do with the form or the fact that the same data source is being used within some context).
I would suggest searching the product feedback site (http://connect.microsoft.com/feedback/default.aspx SiteID=210) to see if there is a defect listed in this area - I would do it, but cannot today.
Woops - found it anyway - http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx FeedbackID=207223
Octavio
I'm using a simple test class "Person" with 3 properties, like (only one property shown here)
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
private string firstName;
public string FirstName
{
get
{
getterCount++;
return (this.firstName);
}
set
{
if (this.firstName != value)
{
this.firstName = value;
NotifyPropertyChanged("FirstName");
}
}
}
Notice the getterCount memeber that is initialized. It counts each getter call of the 3 properties. In the form I have the following code:
public partial class Form1 : Form
{
private Person person = new Person();
public Form1()
{
InitializeComponent();
textBox1.DataBindings.Add("Text", person, "FirstName");
textBox2.DataBindings.Add("Text", person, "FamilyName");
textBox3.DataBindings.Add("Text", person, "Age");
label1.DataBindings.Add("Text", person, "GetterCount");
}
private void button1_Click(object sender, EventArgs e)
{
person.FirstName = "A";
person.FamilyName = "B";
person.Age = 35;
}
}
When the form is first shown, getterCount = 3. After clicking button1, the count = 12. The increase in 9, which is 3*3;
I'm doing this correctly. See the sample property above in my code.
NetPochi
I believe we know for a fact that the data from unrelated object properties are being gotten (Get accessor) unnecessarily, but, do we really know for a fact that the UI Controls are being pushed data unnecessarily That is, how can we measure how many times the text of a textbox is being set. I don't think we can use the TextChanged event because if the data is being pushed unnecessarily, then the textbox text is not actually changing and so the event won't fire.
So I created my own User Control that is basically the same as a TextBox just wrapped so that I can interrogate the Property Text Set routine and sure enough, it looks like not only is the Data Object Property Get routine being called unnecessarily, but also the UI Control Property Set routine is being called unnecessarily, for example, repeatedly setting the Text to the same Text that was previously set because some other data object property has changed.
I know this isn't good news, but I wanted to document somewhere how I confirmed this.
... How difficult could it be to rewrite DataBinding