繁体   English   中英

如何在WPF DataGrid中突出显示行并强制行/单元格刷新?

[英]How to highlight a row and force row/cell refresh in a WPF DataGrid?

这是我关于SOF的第一个问题,所以请温柔地对待我:)

我在XAML中定义了一个简单的WPF DataGrid。 应用程序从文本文件中将“用户”数据(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服务。 websrvice需要的唯一参数是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]);

并且只有最后一行在循环结束时突出显示,此时所有内容都会更新。

此代码的另一个问题是,在提交了所有行之后,“回复”列仅在结尾处刷新,因此没有实时通知用户。

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

谢谢你的帮助,对不起我的长话题。

编辑:如果有更好的方法一起完成这一切,我会打开建议。

首先,通过将此代码放入DataGrid块中的XAML,可以将bacgroundcolor绑定到样式中的属性

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

如果要实时刷新UI,则必须使用backgroud worker来提交用户

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM