我一直在尝试学习并利用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>

我有一个类(批处理),其中包含用于处理属性汇总事件的代码:

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循环。当您执行此操作时,在您的操作完成100%之前,UI将完全阻止(而不是刷新/重新刷新),并且消息泵可以再次运行。

有一些选择可以解决此问题 - 如果您的操作需要一段时间,并且您希望它在运行时进行更新,则可以将foreach循环移至在背景线程上运行的代表。然后,您将使用调度程序将状态更新回到UI线程中。

当您进行长期运行时,这会有几个好处:

  1. 您可以在UI中获得实例反馈/状态
  2. 运行操作时,您的UI保持响应能力。

其他提示

为什么这是个问题?

看起来这个循环应该需要微秒来完成。如果是这样,无论是否在循环末端重新绘制控件都没有明显的区别。

如果列表很大,则应考虑对其进行分配。

如果要获得数据需要这么长时间,则应该在其他线程中进行此操作,如上所述。但是,如果是这样的复杂,我认为您应该真正考虑在按钮点击事件处理程序中没有复杂的逻辑,然后转到更多的MVVM型号。

感谢所有帮助!一旦您让我指向正确的方向,我就可以像我想要的那样使这个工作完全像我想要的那样。有了您的提示和此链接: 工人线程和调度员 我能够使用一些额外的代码来完成它。另外,我再次学到了有关WPF的新知识。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top