值更改后,绑定到ObservableCollection的DataGrid不会立即更新

时间:2019-06-28 10:26:26

标签: wpf mvvm datagrid observablecollection

我有一个名为PingStatisticCollection的ObservableCollection。 IP会定期ping通。成功将成功立即写入0,否则将ObservableCollection的项目写入成功,否则写入1。UI的视觉更新将持续到测试完成为止。如果测试失败,则下一个IP的测试必须等待1000毫秒,如果无法ping通更多IP,则UI的更新时间将更长。在循环中测试单个IP后,如何立即更新UI?

我的观点的一部分:

<DataGrid x:Name="grdStatistic" ItemsSource="{Binding PingStatisticCollection, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" SelectedItem="SelectedPingStatisticElement" 
                      AutoGenerateColumns="False" IsReadOnly="True" AlternatingRowBackground="#FFFFE880"  >
<DataGrid.Columns>
    <DataGridTextColumn Header="IP" Width="100" Binding="{Binding IP}"/>
    <DataGridTemplateColumn Width="70">
        <DataGridTemplateColumn.HeaderTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock>Ping</TextBlock>
                </StackPanel>
            </DataTemplate>
        </DataGridTemplateColumn.HeaderTemplate>

        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal" >
                    <Image Name="imagegreen" Source="/Resources/green.png" Width="20" Height="20"  Margin="5,0" />
                    <Image Name="imagered"  Source="/Resources/red.png"   Width="20" Height="20"  Margin="5,0"/>
                </StackPanel>
                <DataTemplate.Triggers>
                    <DataTrigger Binding="{Binding Path=actPingSuccess, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Value="0">
                        <Setter TargetName="imagegreen" Property="Visibility" Value="Visible"/>
                        <Setter TargetName="imagered" Property="Visibility" Value="Collapsed"/>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Path=actPingSuccess, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Value="1">
                        <Setter TargetName="imagegreen" Property="Visibility" Value="Collapsed"/>
                        <Setter TargetName="imagered" Property="Visibility" Value="Visible"/>
                    </DataTrigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
    <!-- ... -->
</DataGrid.Columns>
</DataGrid> 

//从ViewModel中提取:

//命令绑定到按钮以测试功能

void OnTestIP(object sender) 
{
  string sIP;
  bool bSuccess;

  foreach (var p in PingStatisticCollection)  // load from database
  {
    SelectedPingStatisticElement = p;
    lock(p)
    {
      bSuccess = PingHost(p.IP, 1000 );
      SavePingSuccess(p, bSuccess);
// actual success and last 5 tests determine red, yellow, green iconcolor
      DetermineIconColors(p, PingStatisticCollection);
    }
  }
}

private ObservableCollection<PingStatistic> _PingStatisticCollection;
public ObservableCollection<PingStatistic> PingStatisticCollection
{
    get { return _PingStatisticCollection; }
    set
    { _PingStatisticCollection = value;      OnPropertyChanged("PingStatisticCollection"); }
}

//extracts from Model: 

class PingStatistic: INotifyPropertyChanged
{

  private string _IP;
  public string IP     // +
  {
    get { return _IP; }
    set
    {   if (value != _IP)
        {   _IP = value; OnPropertyChanged("IP");}
    }
  }

  public int actPingSuccess       
  {
    get { return _actPingSuccess; }
    set
    {
      _actPingSuccess = value;
      OnPropertyChanged("actPingSuccess");
    }
  } 
}

目前,在访问每个IP之后,所有IP的IconColors都会更新。我想在访问和评估颜色后立即更新颜色,而不会延迟。有谁知道如何解决这个问题?谢谢伯恩德

1 个答案:

答案 0 :(得分:0)

请尝试将foreach与Task结合使用,而不是使用Parallel.ForEach

await Task.Run(() => Parallel.ForEach(strings, s => { DoSomething(s); //Update the status of IP here));