tags:

views:

96

answers:

1

With the code below I get both the "Firing C Binding" message and the "Firing F Binding" message. Why is that? I'm only expecting to get the "Firing C Binding" message.

using System;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;

class Program : Form
{
    private Label lblC;
    private Label lblF;
    private Button btnCUp;
    private Temp t;

    public Program()
    {
     lblC = new Label();
     lblF = new Label();
     btnCUp = new Button();
     t = new Temp();

     lblC.Location = new Point(22, 21);
     lblC.Size = new Size(35, 13);
     Binding b = new Binding("Text", t, "C");
     b.Format += new ConvertEventHandler(CLabelFormat);
     lblC.DataBindings.Add(b);

     lblF.Location = new Point(108, 21);
     lblF.Size = new Size(35, 13);
     Binding b2 = new Binding("Text", t, "F");
     b2.Format += new ConvertEventHandler(FLabelFormat);
     lblF.DataBindings.Add(b2);

     btnCUp.Location = new Point(45, 55);
     btnCUp.Text = "C Up";
     btnCUp.Click += new EventHandler(btnCUp_Click);

     this.ClientSize = new Size(165, 113);
     this.Controls.Add(lblC);
     this.Controls.Add(lblF);
     this.Controls.Add(btnCUp);
    }

    private void CLabelFormat(object sender, ConvertEventArgs cevent)
    {
     MessageBox.Show("Firing C Binding");
    }

    private void FLabelFormat(object sender, ConvertEventArgs cevent)
    {
     MessageBox.Show("Firing F Binding");
    }

    [STAThread]
    public static void Main()
    {
     Application.EnableVisualStyles();
     Application.SetCompatibleTextRenderingDefault(false);
     Application.Run(new Program());
    }

    private void btnCUp_Click(object sender, EventArgs e)
    {
     t.incC();
    }
}

class Temp : INotifyPropertyChanged
{
    private double tempC;
    private double tempF;

    public event PropertyChangedEventHandler PropertyChanged;

    public Temp()
    {
     tempC = 0;
     tempF = ctof(tempC);
    }

    private void NotifyPropertyChanged(String field)
    {
     if (PropertyChanged != null)
     {
      PropertyChanged(this, new PropertyChangedEventArgs(field));
     }
    }

    private double ctof(double c)
    {
     return c * 9.0 / 5.0 + 32;
    }

    public void incC()
    {
     ++tempC;
     tempF = ctof(tempC);
     NotifyPropertyChanged("C");
     //NotifyPropertyChanged("F");
    }

    public double C
    {
     get { return tempC; }
    }

    public double F
    {
     get { return tempF; }
    }
}

If if remove the comment in front of NotifyPropertyChanged("F") I get four message boxes when I press the button. Two for "Firing C Binding" and two for "Firing F Binding". I only want to get one of each.


EDIT: Adding the implementation of NotifyPropertyChanged Irrelevant after last edit

EDIT: I've tried to look at the source for Binding (using Reflector) to see what it does when a PropertyChanged event is fired, but couln't find anything. Can anyone provide some insight? I want to confirm that it actually does care about what field is changed.

EDIT: Replaced my code with a full compilable example implementation that demonstrates the issue.

A: 

I would presume that when one property changes it is indicating that it may have had an effect on another property, thereby resulting in that property firing an update as well. Quite often, property change events fire for an object even when it hasn't changed because the developer doesn't want to actually check for a change, and so just fires the event in scenarios where it might have changed. My gut instinct suggests this may be what you are experiencing.

However, it could also be that whatever is listening the the PropertyChanged event is not actually checking the name of the property that has changed. This would also cause the same issue.

Jeff Yates
"I would presume that when one property changes it is indicating that it may have had an effect on another property". Where would it "indicate" this? I've added the implementation of NotifyPropertyChanged to my original post to show what's going on in there.
Tobbe
About the PropertyChanged event: Isn't it the Binding class that's listening to that? I hope MS didn't just decide to ignore the property name when they implemented that class :)
Tobbe
I would hope so too, but stranger things have happened.
Jeff Yates
Perhaps you could use Reflector to take a look.
Jeff Yates
I'm sorry to say that I didn't find anything using Reflector. This was the first time I used that program though, so I'm not saying the info isn't there, just that I couldn't find it.
Tobbe