2012-03-13 4 views
4

WPF 응용 프로그램에서 INotifyPropertyChanged를 구현하는 ViewModel에 다음 StepCount 속성이있는 경우 내보기의 TextBox에 바인딩되어 있습니다. XAML에서 데이터 바인딩 값이 다른 스레드에서 업데이트되지 않습니다.

public int StepCount 
{ 
    get { return _stepCount; } 
    set 
    { 
     _stepCount = value; 
     OnPropertyChanged("StepCount"); 
    } 
} 

, 여기에 같은 데이터 바인딩이 모습입니다 : 이것은 위대한 작품을

<TextBox Text="{Binding Path=StepCount}" /> 

, 나는이 STEPCOUNT 값을 변경하는 경우, 텍스트 상자 값 업데이트 따라.

그러나 내 문제는 StepCount를 증가시키는 다른 스레드가 있고이 경우 TextBox 값이 업데이트되지 않는다는 것입니다. 스레드가 끝나면 Textbox 값이 올바른 값으로 업데이트됩니다.

내 다른 스레드가 StepCount를 증가시킬 때마다 업데이트 할 Textbox 값이 필요합니다. 지금 당장 Textbox 값은 스레드가 완료된 후에 만 ​​업데이트를 표시합니다.

다른 스레드가 StepCount를 증가 시키지만 스레드가 끝날 때까지 변경 사항이 UI에 표시되지 않습니다.

아이디어가 있으십니까?

UPDATE

나는 모든 응답을 주셔서 감사합니다. 이러한 특정 바인딩의 경우처럼 이전에 작동했던 코드가 작동을 멈추는 것 같았 기 때문에이 문제는 수수께끼였습니다.

VS 2011 Beta를 설치하면 .NET 4.5 Beta Framework가 설치되고 VS 2011 Beta가 문제의 원인 일 수 있다고 의심되면 .NET 4.5 베타 Framework가 제거되지 않습니다.

이제 .NET 4.5 프레임 워크를 제거하고 .NET 4.0 프레임 워크의 복구 설치를 수행했습니다. 이러한 단계를 완료하면 데이터 바인딩이 올바르게 작동하고 다른 스레드가 StepCount를 증가시킬 때마다 Textbox가 올바르게 업데이트됩니다.

.NET 4.5 베타 프레임 워크는 데이터 바인딩 문제를 일으킬 수 있습니다.

Microsoft에 문제를 제출하면이 문제를 해결할 수 있습니다.

답장을 보내 주셔서 감사합니다.

+2

더 많은 코드를 표시 할 수 있습니까? AFAIK, * * 작동해야합니다. StepCount 모양을 변경하는 코드는 무엇입니까? OnPropertyChanged 메서드는 어떤 모습입니까? –

+0

직접 해보지 않았지만 의존성을 높일 수 있습니까? 다른 스레드의 PropertyChanged 이벤트와 관련이있을 수 있습니다. 그렇지 않은 경우 ui 디스패처를 호출합니다 (옵션 인 경우). – Silvermind

+0

방금 ​​다른 사람이 컴퓨터에서 시험해 보았습니다. 정상적으로 작동했습니다. 내가 생각할 수있는 유일한 차이점은 VS 2011 Beta를 설치했고 일부 데이터 바인딩이 중단되었다는 것입니다. VS 2011 베타를 제거했지만 문제가 해결되지 않았으므로 제거되거나 덮어 쓰기되지 않은 파일이있을 수 있습니다. 나는 내가 찾아서 되돌릴 수있는 것을 볼 것이다. – PocketDews

답변

1

View 모델에서보기를 바인딩 한 WPF 클래스가 UI 스레드 내에서 작동한다는 것을 알았습니다.

이상적으로 WPF Dispatcher 및 Invoke 명령을 사용하여 뷰 모델의 StepCount 속성을 변경해야합니다. 이렇게하면 호출을 적절하게 마샬링합니다.

이 프로세스에 대한 자세한 내용은 this article을 참조하십시오.

+4

WPF에서 데이터 바인딩은 크로스 스레드로 작동합니다. Dispatcher를 사용하여'INotifyPropertyChanged.PropertyChanged'를 실행하지 않아도됩니다. 디스패처는 다른 스레드에서 직접 컨트롤을 조작하려는 경우에만 필요합니다. –

+1

참조 할 기사의 링크를 업데이트 할 수 있습니까? – wil

0

는 지금 테스트, 모두가 XAML에서 다음

확인
public partial class MainWindow : Window 
{ 
    SimpleClass simpleClass = new SimpleClass(10); 
    public MainWindow() 
    { 
     InitializeComponent(); 
     DataContext = simpleClass; 
    } 

    void IncrementViewModelProperty() 
    {    
     simpleClass.StepCount += 11; 
     Thread.Sleep(5000); 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     //works the same 
     //Thread thread = new Thread(() => IncrementViewModelProperty()); 
     //thread.Start(); 
     Action act = IncrementViewModelProperty; 
     act.BeginInvoke(null, null); 
    } 
} 

public class SimpleClass : INotifyPropertyChanged 
{ 
    public SimpleClass(int stepCnt) 
    { 
     StepCount = stepCnt; 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    protected void NotifyPropertyChanged(String info) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(info)); 
     } 
    } 

    public int StepCount 
    { 
     get { return _stepCount; } 
     set 
     { 
      _stepCount = value; 
      NotifyPropertyChanged("StepCount"); 
     } 
    } 
    private int _stepCount; 
} 

작동 :

<StackPanel> 
    <TextBlock Text="{Binding Path=StepCount, Mode=OneWay}" /> 
    <Button Content="Increment value in separate thread" Click="Button_Click" /> 
</StackPanel> 

을하지만! 단추를 빨리 누르고 자주 클릭하면 스레드 풀이 고갈되어 실제로 예상대로 속성을 업데이트하지 않습니다.

관련 문제