2012-03-13 9 views
4

WPFアプリケーションで、INotifyPropertyChangedを実装しているViewModelに次のStepCountプロパティがあり、それをビューのTextBoxにバインドしています。 XAMLでデータバインディングの値が他のスレッドから更新されていない

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

、ここでのデータバインディングは次のようになります。これは素晴らしい作品、と私はそれに応じStepCount値、テキストボックスの値の更新を変更した場合

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

しかし、私の問題は、StepCountをインクリメントしている別のスレッドがあり、この場合TextBox値が更新されていないことです。スレッドが終了すると、Textboxの値が正しい値に更新されます。

他のスレッドがStepCountをインクリメントするたびに、テキストボックスの値を更新する必要があります。今のように、Textboxの値は、スレッドが終了した後にのみ更新を表示します。

他のスレッドはStepCountをインクリメントしていますが、スレッドが終了するまでその変更はUIに表示されません。

UPDATE

私は、すべての応答を感謝しています。これらの特定のバインディングの場合のように、以前は動作していたコードが機能しなくなったように見えるので、この問題は困惑していました。

VS 2011 Betaをインストールすると、.NET 4.5 Beta Frameworkがインストールされますが、VS 2011 Betaをアンインストールして問題が発生する可能性がある疑いで.NET 4.5ベータ版をアンインストールしませんでした。

私は今、.NET 4.5フレームワークをアンインストールし、.NET 4.0フレームワークの修復インストールを行いました。これらのステップを完了すると、データバインディングが正しく機能し、別のスレッドがStepCountをインクリメントするたびにテキストボックスが正しく更新されるようになりました。

.NET 4.5ベータ版のフレームワークは、データバインディングに問題を引き起こす可能性があります。

私はMicrosoftに問題を提出してこれをフォローアップします。

お返事ありがとうございます。

+2

さらにコードを表示できますか? AFAIK、これは*うまくいくはずです。 StepCountの外観を変更するコードは何ですか? OnPropertyChangedメソッドはどのように見えますか? –

+0

自分で試したことはありませんが、それを依存性プロパティにすることはできますか?他のスレッドのPropertyChangedイベントと何か関係があるかもしれません。それ以外の場合は、uiディスパッチャを使用して起動します(オプションの場合)。 – Silvermind

+0

私はちょうど別の人に自分のコンピュータでそれを試してもらいました。私が考えることができる唯一の違いは、私はVS 2011 Betaをインストールし、私のデータバインディングのいくつかが壊れたことです。 VS 2011ベータ版をアンインストールしましたが、問題が修正されなかったため、削除または上書きされなかったファイルがある可能性があります。私が見つけて返すことができるものを見ていきます。 – PocketDews

答えて

1

ビューモデルにビューをバインドしたWPFクラスがUIスレッド内で動作することがわかりました。

WPFディスパッチャーとInvokeコマンドを使用して、ビューモデルのStepCountプロパティを変更するのが理想的です。これは、呼び出しを適切にマーシャリングします。

このプロセスの詳細については、this articleを参照してください。ちょうど今、テスト済み

+4

WPFデータバインディングでは、クロススレッドが機能します。ディスパッチャーを使用して 'INotifyPropertyChanged.PropertyChanged'を起動する必要はありません。ディスパッチャは、別のスレッドからコントロールを直接操作したい場合にのみ必要です。 –

+1

参考資料にリンクを更新してください。 – wil

0

、それはXAMLで[OK]を

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> 

しかし!ボタンを速く頻繁にクリックすると、スレッドプールが枯渇してしまい、実際には予想通りにプロパティを更新しません。

関連する問題