【问题标题】:DataGrid bound to ObservableCollection doesn't update immediately after values changed绑定到 ObservableCollection 的 DataGrid 在值更改后不会立即更新
【发布时间】:2019-11-10 07:32:42
【问题描述】:

我有一个名为 PingStatisticCollection 的 ObservableCollection。 IP 会定期 ping 通。成功将立即写入 ObservableCollection 的项目,为 0 表示成功,否则为 1。UI 的视觉更新持续到测试完成。当测试失败时,下一个 IP 的测试必须等待 1000 毫秒,如果更多的 IP 无法 ping 通,则 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 的 IconColors 在访问每个 IP 后都会更新。我想在访问和评估后立即更新颜色。有人知道如何解决这个问题吗?谢谢,伯恩德

【问题讨论】:

    标签: wpf mvvm datagrid observablecollection


    【解决方案1】:

    不要使用foreach,而是尝试将Parallel.ForEach 与Task 一起使用。

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

    【讨论】:

    • 亲爱的布赖恩,我真的很高兴这么快就得到了我的问题的答案。由于我对 ansynchronas 编程的了解不是很深,我很高兴使用以下代码完成我的任务: void OnTestIP(object sender) { BackgroundWorker worker = new BackgroundWorker(); worker.DoWork += worker_DoWork; worker.RunWorkerCompleted += worker_RunWorkerCompleted; worker.RunWorkerAsync(PingStatisticCollection);我必须承认我完全不理解你的解决方案。非常感谢您的帮助,伯恩德
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-15
    • 2020-03-23
    • 2012-02-29
    • 2011-10-25
    • 2011-06-27
    相关资源
    最近更新 更多