簡體   English   中英

C#WPF OnPropertyChanged在foreach循環中

[英]C# WPF OnPropertyChanged Within a foreach loop

我一直在努力學習並利用WPF和數據綁定。 我有一個列表視圖,其中有一列顯示三個圖像中的一個,如下所示:

<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>

我有一個類(BatchQueueItem),其中包含處理PropertyChange事件的代碼:

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));
    }
  }

我在listview窗口頁面上有一個按鈕:

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循環的每次迭代都會更新相應行的圖像。 毫無疑問,我錯過了關於這一切如何運作的重要事項。 有小費嗎?

我遇到的問題是,在foreach循環完成並且btnStart_Click()方法完成之后,圖像才會更新。 一旦發生這種情況,所有圖像都會按預期更新,而不是一次性迭代。

我想要的,以及我認為會發生的是,foreach循環的每次迭代都會更新相應行的圖像。 毫無疑問,我錯過了關於這一切如何運作的重要事項。 有小費嗎?

這是您如何更新的問題。

問題不在於UI沒有更新 - 在內部,它確實如此。 問題是你在主UI線程上進行了這個更新,以及你的foreach循環。 執行此操作時,UI將被完全阻止(而不是刷新/重繪),直到您的操作完成100%,並且消息泵可以再次運行。

有一些方法可以解決這個問題 - 如果你的操作需要一段時間,並且你希望它在運行時更新,你可以將foreach循環移動到一個在后台線程上運行的委托中。 然后,您將使用Dispatcher將狀態更新重新調用回UI線程。

當您進行長時間運行時,這有幾個好處:

  1. 您可以在UI中獲取實例反饋/狀態
  2. 您的UI在您的操作運行時保持響應。

為什么這是個問題?

看起來這個循環應該花費幾微秒才能完成。 如果是這樣,那么控件是否在循環結束時重繪是沒有明顯區別的。

如果列表很大,你應該考慮分頁。

如果獲取數據需要很長時間,您應該在不同的線程中執行此操作,如上所述。 但是,如果它很復雜,我認為你應該真正關注按鈕點擊事件處理程序中沒有復雜的邏輯,並轉向更多的MVVM模型。

感謝所有的幫助! 一旦你讓我指向了正確的方向,我就能夠像我想的那樣工作。 使用您的提示和此鏈接: 工作線程和調度程序我能夠使用一些額外的代碼行。 另外,我再次學到了一些關於WPF的新知識。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM