2011-02-02 14 views

答えて

4

WPFを使用しているときにバックグラウンドスレッドの処理を簡略化するBackgroundWorkerクラスを使用できます。 これにはWeb上に多くの例があります。ここでは、2つのCodeProjectのから、それはより多くの例を見つけるのは簡単です:

http://www.codeproject.com/Tips/83317/BackgroundWorker-and-ProgressBar-demo.aspx http://www.codeproject.com/KB/cpp/BackgroundWorker_Threads.aspx

+1

しかし、私はバックグラウンドワーカーのコントロールにアクセスする際、その投げる例外は:呼び出し元のスレッドが異なるため、このオブジェクトにアクセスすることはできませんスレッドはそれを所有しています。 – Sandy

+0

progressBarコントロールを更新するには、BackgroundWorkerイベント(ProgressChanged、RunWorkerCompleted)を使用する必要があります。これらのイベントのハンドラー内では、問題なくUIコントロールにアクセスできます。 http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx –

1

私はプレゼンテーションモデルを経由して表示状態を制御することを好みます。ビューは、Workerスレッドを開始し、UI同期コンテキストで進行状況値を更新するプレゼンテーションモデルへのアドレスの項目を設定する必要がある場合。

public class SampleModel : ObservableObject 
{ 
    private ObservableCollection<string> _items = new ObservableCollection<string>(); 
    public IEnumerable<string> Items 
    { 
     get 
     { 
      return this._items; 
     } 
    } 

    private int _progress; 
    public int Progress 
    { 
     get 
     { 
      return this._progress; 
     } 
     set 
     { 
      if (this._progress != value) 
      { 
       this._progress = value; 
       this.OnPropertyChanged("Progress"); 
      } 
     } 
    } 

    public void Fill() 
    { 
     this.Progress = 0; 
     var sc = SynchronizationContext.Current; 

     new Thread(new ThreadStart(() => 
      { 
       for (int i = 0; i < 100; i++) 
       { 
        sc.Post(p => 
         { 
          this._items.Add(i.ToString()); 
          this.Progress ++; 
         }, null); 
        Thread.Sleep(100); 
       } 

       sc.Post(p => 
       { 
        this.Progress = 0; 
       }, null); 

      })) 
      .Start(); 
    } 
} 

XAML:

<DockPanel> 
    <ProgressBar Minimum="0" 
       Maximum="100" 
       Height="50" 
       Value="{Binding Progress}" 
       DockPanel.Dock="Top"> 
     <ProgressBar.Style> 
      <Style TargetType="ProgressBar"> 
       <Setter Property="IsEnabled" 
         Value="True"/> 
      </Style> 
     </ProgressBar.Style> 
    </ProgressBar> 
    <Button Name="Start" 
      DockPanel.Dock="Top">Start</Button> 
    <ListView Name="List" 
       ItemsSource="{Binding Items}"/> 
</DockPanel> 

そして、背後にあるコード:

public MainWindow() 
    { 
     InitializeComponent(); 
     this.Model = new SampleModel(); 
     this.Start.Click += new RoutedEventHandler(Start_Click); 
    } 

    void Start_Click(object sender, RoutedEventArgs e) 
    { 
     this.Model.Fill(); 
    } 

    protected SampleModel Model 
    { 
     get 
     { 
      return (SampleModel)this.DataContext; 
     } 
     set 
     { 
      this.DataContext = value; 
     } 
    } 
関連する問題