2009-04-07 10 views
2

아래 코드를 사용하면 Firing C Binding 메시지와 Firing F Binding 메시지가 모두 표시됩니다. 왜 그런가요? Firing C Binding 메시지 만 수신되기를 기대합니다. 내가 NotifyPropertyChanged("F") 앞에있는 주석을 제거하면 I 버튼을 누를 때바운드 속성이 변경되지 않은 경우에도 바인딩이 실행되는 이유는 무엇입니까?

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

, 그럼 나는 네 개의 메시지 상자를 얻을. 2 개는 "Firing C Binding"용이고 2 개는 "Firing F Binding"용입니다.

각 코드 중 하나만 가져 오도록 코드를 수정할 수 있습니까?


편집 : 나는 바인딩하여 PropertyChanged 이벤트가 발생할 때 그것이 무엇을보고 (리플렉터를 사용)에 대한 소스를보고했지만, 아무것도 찾을 수 couln't 한. 누구나 통찰력을 제공 할 수 있습니까? 나는 그것이 어떤 분야가 바뀌 었는지에 대해 관심이 있는지 확인하기를 원합니다.

편집 : 내 코드를 문제를 설명하는 전체 컴파일 가능한 예제 구현으로 바 꾸었습니다.

답변

0

하나의 속성이 변경되면 다른 속성에 영향을 미쳤다는 것을 나타내므로 해당 속성이 업데이트를 실행하게됩니다. 개발자가 실제로 변경 사항을 확인하기를 원하지 않기 때문에 속성 변경 이벤트가 변경되지 않은 경우에도 속성 변경 이벤트가 발생하는 경우가 많으므로 변경된 시나리오에서 이벤트가 발생합니다. 내 직감은 이것이 당신이 경험하고있는 것일 수도 있음을 암시합니다.

그러나 PropertyChanged 이벤트를 수신하는 것은 실제로 변경된 속성의 이름을 확인하지 않을 수도 있습니다. 이것은 또한 동일한 문제를 일으킬 것입니다.

t.PropertyChanged += t_PropertyChanged; 

void t_PropertyChanged(object sender, PropertyChangedEventArgs e) { 
    MessageBox.Show("Property Changed: " + e.PropertyName); 
} 

Binding Format 이벤트가 뭔가 다른 :

+0

"한 속성이 변경되면 다른 속성에 영향을 미쳤음을 나타냅니다." 어디에서 "표시"합니까? NotifyPropertyChanged 구현을 원래 게시물에 추가하여 거기에 무슨 일이 일어나고 있는지 보여줍니다. – Tobbe

+0

PropertyChanged 이벤트에 관하여 : 듣고있는 Binding 클래스가 아닌가? 나는 MS가 그 클래스를 구현할 때 속성 이름을 무시하기로 결정하지 않았기를 바란다 :) – Tobbe

+0

나는 또한 그렇게 희망하지만, 이상한 일이 일어났다. –

2

하여 PropertyChanged 이벤트는 당신이 자신을 테스트 할 수있는, 한 번 발사됩니다

서식 이벤트가 발생할 때마다 BindingManagerBase 변화의 현재 값 포함 :

  • 처음으로 prope rty가 바인딩됩니다.
  • 위치가 변경 될 때마다.
  • 데이터 바인딩 된 목록이 정렬되거나 필터링 될 때마다 DataView에서 목록을 제공 할 때 수행됩니다.

따라서 현재 값이 변경되면 속성 이벤트가 발생합니다.

관련 문제