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