2010-05-12 7 views
1

프로세스를 특정 횟수만큼 반복하는 데 걸리는 시간을 계산하는 프로그램을 만들고 싶습니다. 나는이 예제를 위해 이것을 많이 축소했다.WPF multibound textblock이 업데이트되지 않습니다.

Count: <TextBox x:Name="txtCount" Text="{Binding Count, Mode=TwoWay}" Width="50"/> 
Days: <TextBox x:Name="txtDays" Text="{Binding Days, Mode=TwoWay}" Width="50"/> 

등처럼 multibound하는 TextBlock의 :

<TextBlock x:Name="tbkTotal"> 
    <TextBlock.Text> 
     <MultiBinding StringFormat="Days: {0}, Count: {1}"> 
      <Binding Path="Days" /> /* This isn't updating */ 
      <Binding Path="Count" /> 
     </MultiBinding> 
    </TextBlock.Text> 
</TextBlock> 

내의 DataContext가 번째 윈도에서 설정

그래서, 나는 몇 가지 클래스의 속성에 바인딩 된 텍스트 상자가 있습니다. xaml.cs 파일. 데이즈 입력이 정확하게 변화를 반영하더라도,

public Window1() 
     { 
      InitializeComponent(); 
      Sample sample = new Sample(); 
      this.DataContext = sample; 
     } 

나는 잘 Count 속성을 가진 multibound 된 본체를 업데이트 할 수 있지만, 일 속성은 항상 0을 보여줍니다. 나는 이것이 내 접근자가 일 동안 다르다는 것, 즉 Set 메서드라고 생각한다. 이 클래스는 다른 파일에 있습니다.

public class Sample : INotifyPropertyChanged 
    { 
     private int _count; 
     private TimeSpan _span; 

     public int Count 
     { 
      get { return _count; } 
      set 
      { 
       _count = value; 
       NotifyPropertyChanged("Count"); /* Doesn't seem to be needed, actually */ 
      } 
     } 

     public TimeSpan Span { get { return _span; } } 

/* The idea is to provide a property for Days, Hours, Minutes, etc. as conveniences to the inputter */ 

     public double Days 
     { 
      get { return _span.Days; } 
      set 
      { 
       TimeSpan ts = new TimeSpan(); 
       double val = value > 0 ? value : 0; 
       ts = TimeSpan.FromDays(val); 
       _span.Add(ts); /* !! This turned out to be the problem, lol - see SixLetterVariables' answer below. */ 
       NotifyPropertyChanged("Span"); /* Here I can only get it to work if I notify that Span has changed - doesn't seem to be aware that the value behind Days has changed. */ 
      } 
     } 

     private void NotifyPropertyChanged(string property) 
     { 
      if (null != this.PropertyChanged) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(property)); 
      } 
     } 
     public Sample() 
     { 
      _count = 0; 
      _span = new TimeSpan(); 
     } 
     public event PropertyChangedEventHandler PropertyChanged; 
    } 
+2

당신의 NotifyPropertyChanged에서 먼저 널 (null)을 검사하는 경우, 당신은 정말 첫 번째 사본은 함수 로컬 PropertyChangedEventHandler에 this.PropertyChanged한다 그 다음에 당신의 메소드가 널 체크와 이벤트 발생 사이에서 핸들러가 제거 된 경합 조건의 (매우 작지만 존재하는) 기회를 남겨 둡니다. – JustABill

답변

1

첫째 TimeSpan 당신이 어떤 작업의 결과를 저장해야합니다, 그래서 그렇지 않으면 효과적으로 어떤 조합입니다, 불변의 구조체이다. 또한, 당신이 변경되는 모두 SpanDays에 대한 OnPropertyChanged를 호출해야합니다 :

public double Days 
{ 
    get { return _span.Days; } 
    set 
    { 
     double val = value > 0 ? value : 0; 

     // TimeSpan is an immutable struct, must store the result of any 
     // operations on it 
     _span = TimeSpan.FromDays(val); 

     this.OnPropertyChanged("Days"); 
     this.OnPropertyChanged("Span"); 
    } 
} 

// This is preferred way for handling property changes 
private event PropertyChangedEventHandler propertyChanged; 
public event PropertyChangedEventHandler PropertyChanged 
{ 
    add { this.propertyChanged += value; } 
    remove { this.propertyChanged -= value; } 
} 

protected virtual void OnPropertyChanged(string propertyName) 
{ 
    PropertyChangedEventHandler handler = this.propertyChanged; 
    if (null != handler) 
    { 
     handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 
+0

나는 그것도 생각했지만 아무런 차이가 없다. –

+0

코드를 수정 했으므로'_span'을 저장해야합니다. 'TimeSpan.Add'는'TimeSpan'을 수정하지 않고 새로운 것을 반환합니다. – user7116

+0

당신은 그것을 못 박았습니다. 나는 너브 야. 고마워요 :) –

관련 문제