1

私はWPFとデータバインディングを学び、活用しようとしています。このスニペットに示すように、3つの画像のいずれかを表示する列を持つリストビューがあります。

<GridViewColumn Header="Status" Width="50">
  <GridViewColumn.CellTemplate>
    <DataTemplate>
      <Image x:Name="TheImage" Height="18"/>
        <DataTemplate.Triggers>
          <DataTrigger Binding="{Binding Path=Status}" Value="queued">
            <Setter TargetName="TheImage" Property="Source" Value="Images\que_48.png" />
          </DataTrigger>
          <DataTrigger Binding="{Binding Path=Status}" Value="completed">
            <Setter TargetName="TheImage" Property="Source" Value="Images\complete_48.png" />
          </DataTrigger>
          <DataTrigger Binding="{Binding Path=Status}" Value="failed">
            <Setter TargetName="TheImage" Property="Source" Value="Images\fail_48.png" />
          </DataTrigger>
        </DataTemplate.Triggers>
      </DataTemplate>
    </GridViewColumn.CellTemplate>
  </GridViewColumn>

PropertyChangeイベントを処理するための次のコードを含むクラス(BatchQueueItem)があります。

public string status;
  public string Status
  {
    get { return status; }
    set 
    { 
      status = value;
      OnPropertyChanged("Status");
    }            
  }
  // Create the OnPropertyChanged method to raise the event

  public event PropertyChangedEventHandler PropertyChanged;    
  private void OnPropertyChanged(string status)
  {
    if (PropertyChanged != null)
    {
      PropertyChanged(this, new PropertyChangedEventArgs(status));
    }
  }

そして、リストビューウィンドウページにボタンがあります。

private void btnStart_Click(object sender, RoutedEventArgs e)
{
  foreach (var item in listView1.Items)
  {
    BatchQueueItem bqi = (BatchQueueItem)item;
    string currFile = bqi.CurrFile;
    if (mainWindow.isIsbnInFileName(ref currFile))
    {
       bqi.Status = "completed";
    }
    else
    {
      bqi.Status = "failed";
    }
  }
}

私が抱えている問題は、foreachループが完了し、btnStart_Click()メソッドが完了するまで画像が更新されないことです。それが発生すると、すべてのイメージが期待どおりに更新されますが、繰り返しではなく一度にすべて更新されます。

私が望んでいたこと、そして私が起こると思ったことは、foreachループの各反復が対応する行のイメージを更新するということでした。間違いなく、これがどのように機能するかについて重要な何かが欠けています。任意のヒント?

4

3 に答える 3

4

私が抱えている問題は、foreachループが完了し、btnStart_Click()メソッドが完了するまで画像が更新されないことです。それが発生すると、すべてのイメージが期待どおりに更新されますが、繰り返しではなく一度にすべて更新されます。

私が望んでいたこと、そして私が起こると思ったことは、foreachループの各反復が対応する行のイメージを更新するということでした。間違いなく、これがどのように機能するかについて重要な何かが欠けています。任意のヒント?

これは、更新方法の問題です。

問題は、UIが更新されていないことではなく、内部的には更新されています。問題は、メインUIスレッドでこの更新とforeachループを実行していることです。これを行うと、操作が100%完了するまで、UIは完全にブロックされ(更新/再描画はされません)、メッセージポンプを再度実行できるようになります。

これを回避するオプションがあります。操作に時間がかかり、実行時に更新したい場合は、foreachループをバックグラウンドスレッドで実行されるデリゲートに移動できます。次に、ディスパッチャーを使用して、ステータスの更新を呼び出してUIスレッドに戻します。

長時間の操作を行う場合、これにはいくつかの利点があります。

  1. UIでインスタンスのフィードバック/ステータスを取得できます
  2. 操作の実行中、UIの応答性は維持されます。
于 2009-09-26T00:28:35.427 に答える
0

なぜこれが問題なのですか?

このループが完了するまでにマイクロ秒かかるようです。その場合、ループの最後にコントロールが再描画されるかどうかに関係なく、知覚できる違いはありません。

リストが非常に大きい場合は、とにかくページングを検討する必要があります。

データの取得に時間がかかる場合は、上記のように、別のスレッドでデータを取得する必要があります。ただし、それがそれほど複雑な場合は、ボタンクリックイベントハンドラーに複雑なロジックがないことを実際に確認し、MVVMモデルに移行する必要があると思います。

于 2009-09-26T01:56:03.537 に答える
0

すべての助けに感謝します!あなたが私を正しい方向に向けさせれば、私はこれを私が望んでいたように正確に機能させることができました。あなたのヒントとこのリンクで:Worker Threads&Dispatcher 私は数行のコードを追加することでそれを実行することができました。さらに、WPFについてもう一度新しいことを学びました。

于 2009-09-26T03:29:15.887 に答える