这是我关于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]);
当循环结束时,只有最后一行突出显示。
此代码的另一个问题是,只有在提交了所有行之后,“回复”列才会在结尾处刷新,因此没有实时通知用户。
如何以智能方式突出显示当前处理的行,最重要的是,如何在每次回复后以及处理下一行之前更新回复单元格。
感谢您的帮助,对不起我的长期问题感到抱歉。
编辑:如果有更好的方式一起完成这项工作,我会获得建议。
答案 0 :(得分:2)
首先,您可以将此代码绑定到DataGrid
块中的XAML
<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();
答案 1 :(得分:0)
这可能是一个选择:
将以下内容添加到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 );