如何在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列才会在最后刷新,因此没有实时通知用户。
如何以智能的方式突出显示当前处理的行,最重要的是,如何在每次回复后和处理下一行之前更新回复单元格
谢谢你的帮助,很抱歉问了我这么长的问题。
编辑:如果有更好的方法可以一起做到这一点,我愿意接受建议。
首先,您可以将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 );