如何在WPF数据网格中高亮显示行并强制刷新行/单元格

本文关键字:刷新 单元格 显示 高亮 WPF 数据 数据网 网格 | 更新日期: 2023-09-27 18:28:00

这是我在SOF上的第一个问题,所以请对我温和一点:)

我在XAML中定义了一个简单的WPF数据网格。应用程序从文本文件将"用户"数据(FirstName、LastName)加载到网格中,从文本文件加载条目后,用户点击提交按钮,我想迭代列表中的项目,并将每一行提交给创建用户的Web服务,然后在网格中显示Web服务的回复。

为了让用户了解情况,我希望以某种方式突出显示当前提交的行,并希望在收到响应后立即显示消息。如果消息是错误,则用红色突出显示该行;如果成功,则用绿色突出显示。

看起来很简单。。。

我有一个简单的GridDto类,它表示要映射到每一行的数据。它实现了INotifyPropertyChanged接口。为了简单起见,我将其定义如下:

class GridDto : INotifyPropertyChanged
{
  public string FirstName { get; set; }
  public string LastName { get; set; }
  private string Reply;
  public string Reply
  {
      get
      {
        return this.message;
      }
      set
      {
          this.message = value;
          this.PropertyChanged(this, new PropertyChangedEventArgs("Reply"));
      }
   }

网格接受文本文件中的FirstName和LastNames列表。

我填充这个网格的方式是构建ObservableCollection<GridDto>的集合,然后我这样做:

resultGrid.ItemsSource = ConvertTextDtoToGridDtos(result.Elements);

到目前为止还不错。现在,我想将网格中的每一行提交给创建用户的Web服务。Web服务唯一需要的参数是FirstName和LastName。

由于我是WPF的新手,我不知道该怎么做。以下是我迄今为止所做的:

for (int i = 0; i < resultGrid.Items.Count - 1; i++)
{
    var dto = (GridDto)this.resultGrid.Items[i];
    var color = Color.FromRgb(192, 192, 25);
    try{
       // Do webservice call using the dto data
    }
    catch(Exception ex){
      dto.Reply = ex.Message;
      color = Color.FromRgb(255, 0, 0);
    }
  DataGridRow row = (DataGridRow)resultGrid.ItemContainerGenerator.ContainerFromIndex(i);
  row.Background = new SolidColorBrush(color) { Opacity = 0.45 };
}

这在一定程度上起作用,但不会突出显示当前正在处理的行。

我试着在我的循环中添加以下内容

resultGrid.SelectedIndex = i;

或者。。。

resultGrid.SelectedItem = resultGrid.Items[i];
resultGrid.ScrollIntoView(resultGrid.Items[i]);

只有最后一行在循环结束时高亮显示,此时所有内容似乎都已更新。

此代码的另一个问题是,只有在提交了所有行之后,Reply列才会在最后刷新,因此没有实时通知用户。

如何以智能的方式突出显示当前处理的行,最重要的是,如何在每次回复后和处理下一行之前更新回复单元格

谢谢你的帮助,很抱歉问了我这么长的问题。

编辑:如果有更好的方法可以一起做到这一点,我愿意接受建议。

如何在WPF数据网格中高亮显示行并强制刷新行/单元格

首先,您可以将bacgroundcolor绑定到样式中的属性,方法是将此代码放在DataGrid块中的XAML中

        <DataGrid.RowStyle>
            <Style TargetType="DataGridRow">
                <Setter Property="Background" Value="{Binding Path=Color}"/>
            </Style>
        </DataGrid.RowStyle>

如果你想实时刷新UI,你必须使用后台工作程序来提交用户

            BackgroundWorker bw = new BackgroundWorker();
            bw.DoWork += delegate(object s, DoWorkEventArgs we)
            {
                for (int i = 0; i < resultGrid.Items.Count - 1; i++)
                {
                    var dto = (GridDto)this.resultGrid.Items[i];
                    var color = Color.FromRgb(192, 192, 25);
                    try
                    {
                        // Do webservice call using the dto data
                    }
                    catch (Exception ex)
                    {
                        dto.Reply = ex.Message;
                        color = Color.FromRgb(255, 0, 0);
                    }
                    dto.Color = new SolidColorBrush(color) { Opacity = 0.45 };
                }
            };
            bw.RunWorkerAsync();

这可能是一个选项:

将以下内容添加到GridDto

private Brush validationBrush = Brushes.White;
public Brush ValidationBrush
{
  get { return validationBrush; }
  set
  {
    validationBrush = value;
     this.PropertyChanged(this, new PropertyChangedEventArgs("ValidationBrush"));
  }
}

这在Xaml 中的DataGrid标签中

  <DataGrid.Resources>
    <Style TargetType="{x:Type DataGridRow}">
      <Setter Property="Background" Value="{Binding Path=ValidationBrush}"/>
    </Style>
  </DataGrid.Resources>

更新GridDto项目上的ValidationBrush将更改RowColor

编辑

这会有用吗:

var MyGridDtoCollection = ConvertTextDtoToGridDtos(result.Elements);
resultGrid.ItemsSource = MyGridDtoCollection;
Action a = ( ) =>
{
  foreach ( var gridDto in MyGridDtoCollection )
  {
    gridDto.ValidationBrush = Brushes.Black;
    System.Threading.Thread.Sleep( 500 );
  }
};
a.BeginInvoke( result =>
{
  a.EndInvoke( result );
} , null );