私は、背景のワーカースレッドからViewModel
(MVVM)のバウンドプロパティを変更するときに例外が発生せず、ビューが正しく更新されていることに気付きました。つまり、ViewModel
のすべての変更をUIスレッドにマーシャリングするwpfデータバインディングに安全に頼ることができますか?私は、INotifyPropertyChanged.PropertyChanged
がUIスレッドで起動されることを(ViewModel
では)確かめなければならないと読んだと思います。これは3.5などで変更されましたか?WPFデータバインディング・マーシャルはUIスレッドに変更されますか?
答えて
スカラーの場合ははい、コレクションの場合はありません。コレクションの場合は、マーシャリングする特別なコレクション、またはDispatcher
を使用して手動でUIスレッドに手動でマーシャリングする必要があります。
INotifyPropertyChanged.PropertyChanged
ではないため、INotifyCollectionChanged.CollectionChanged
はUIスレッドで起動する必要があります。以下は、あなたのためにWPFマーシャリングプロパティの変更を証明する非常に簡単な例です。
Window1.xaml.cs:
using System.ComponentModel;
using System.Threading;
using System.Windows;
namespace WpfApplication1
{
public partial class Window1 : Window
{
private CustomerViewModel _customerViewModel;
public Window1()
{
InitializeComponent();
_customerViewModel = new CustomerViewModel();
DataContext = _customerViewModel;
var thread = new Thread((ThreadStart)delegate
{
while (true)
{
Thread.Sleep(2000);
//look ma - no marshalling!
_customerViewModel.Name += "Appended";
_customerViewModel.Address.Line1 += "Appended";
}
});
thread.Start();
}
}
public abstract class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class CustomerViewModel : ViewModel
{
private string _name;
private AddressViewModel _address = new AddressViewModel();
public string Name
{
get { return _name; }
set
{
if (_name != value)
{
_name = value;
OnPropertyChanged("Name");
}
}
}
public AddressViewModel Address
{
get { return _address; }
}
}
public class AddressViewModel : ViewModel
{
private string _line1;
public string Line1
{
get { return _line1; }
set
{
if (_line1 != value)
{
_line1 = value;
OnPropertyChanged("Line1");
}
}
}
}
}
Window1.xaml:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<StackPanel>
<TextBox Text="{Binding Name}"/>
<TextBox Text="{Binding Address.Line1}"/>
</StackPanel>
</Window>
私は.NETの2.0と以前の化身であなたが原因と、InvalidOperationExceptionを受けているだろうと信じています上記の例を実行したときのスレッドの親和性(bitbonkの投稿リンクは2006年)です。
3.5では、WPFがバックグラウンドスレッドのプロパティ変更をマーシャリングしてディスパッチャに表示されます。
つまり、要するに、対象とする.NETのバージョンによって異なります。混乱がなくなることを願っています。
私の仲間Lab49'ersの一つはここに2007年にそれについてブログ:
しかし、2.0にはWPFがありませんでした。3.0を意味しますか? – bitbonk
- 1. WPFデータバインディング:項目の変更はどのように検出されますか?
- 2. データバインディングは常にUIスレッドにマーシャリングしますか?
- 3. WPFデータバインディングが更新されない
- 4. mvvm wpfのUI以外のスレッドからUIスレッドにアクセス
- 5. WPFファイアプロパティmvvmでuiを更新すると変更される
- 6. c#WPF UIがハングするUIスレッドのデータを更新する
- 7. アンドロイドのUIが別のスレッドから変更される
- 8. wpfデータコンテキストの変更でUIが更新されない
- 9. WPFは、私はUIスレッドから呼び出された関数を持つUIスレッド
- 10. WPF 4.0でデータバインディングが実装される方法に変更はありますか?
- 11. WPFネストされたデータバインディングはランダムに動作します
- 12. WPFで依存関係のプロパティを変更するUIスレッドにアクセス
- 13. WPFデータバインディング手動更新
- 14. WPFは変数の変更を待ってからUIを更新します
- 15. WPFボタンのテキストが変更されないUIがスレッドコードからロックされる
- 16. XAMLデータバインディングでプロパティが変更されたときにUIが更新されない
- 17. WPF XAMLデータバインディングと動的にサイズ変更するUserControl
- 18. AsyncTask onProgressUpdateは、UIスレッドのUIをすぐに変更しません。
- 19. WPFデータバインディングと型変換
- 20. WPF UIの変更が延期される
- 21. スレッド:スレッドをブロックせずにUIを更新しますか?
- 22. Android bluetooth:UIスレッドから開始されたスレッドはUIスレッドをブロックします
- 23. ContentProvider insert()は常にUIスレッドで実行されますか?
- 24. ConcurrentBag型コレクションの変更時にWPF UIが更新されない
- 25. WPFスライダ - 値がUIから変更されたときに通知
- 26. wpfイベントのハンドラがUIスレッドで呼び出されることは保証されますか?
- 27. クラスのメンバー変数からのデータバインディング。 WPF
- 28. データバインディングでUI要素が更新されない
- 29. WPFアプリケーションのUIをスレッドから更新するにはどうすればよいですか?
- 30. ListBoxとのデータバインディング中にWPF UIがフリーズする
どのような複雑なスカラー型は? ViewModelに「MyCompositeObject」タイプのプロパティがある場合はどうなりますか? – bitbonk
はい、そのパスにコレクションがない限り、プロパティパスに沿った変更はすべて正しくマーシャリングされます。 –
UIのスレッド上にそのプロパティの変更を読み込んだのは初めてです:http://blogs.msdn.com/dancre/archive/2006/07/23/676300.aspx – bitbonk