首页 文章

刷新OxyPlot图表

提问于
浏览
4

我正在开发一个WPF应用程序 . 这个应用程序使用OxyPlot chart control . 我让用户进行计算 . 用户可以以网格和图表形式查看结果 . 为了做到这一点,我有以下内容:

home.xaml

<DataGrid x:Name="resultDataGrid" ItemsSource="{Binding Items}">
  <DataGrid.Columns>
    <DataGridTextColumn Header="#" Binding="{Binding Number}" />
    <DataGridTextColumn Header="Description" Binding="{Binding Description}" />
  </DataGrid.Columns>
</DataGrid>

<oxy:Plot x:Name="resultGraph" Background="Transparent" Height="400" HorizontalContentAlignment="Stretch" VerticalAlignment="Stretch" Visibility="Collapsed">
  <oxy:Plot.Series>
    <oxy:LineSeries ItemsSource="{Binding Points}" MarkerType="Circle"  Title="Result" />
  </oxy:Plot.Series>
</oxy:Plot>

<StackPanel Orientation="Horizontal">
  <Button x:Name="executeButton" Click="executeButton_Click" />
  <Button x:Name="viewData" Click="viewData_Click" />
  <Button x:Name="viewChart" Click="viewChart_Click" />
</StackPanel>

home.xaml.cs

public partial class Home: Page
{
  private MyViewModel viewModel = null;
  public Home()
  {
    InitializeComponent();

    viewModel = new MyViewModel();
    this.DataContext = viewModel;
  }

  private void executeButton_Click(object sender, RoutedEventArgs e) {
    viewModel.Execute();
  }

  private void viewData_Click(object sender, RoutedEventArgs e) 
  {
    resultDataGrid.Visibility = System.Windows.Visibility.Visible;
    resultGraph.Visibility = System.Windows.Visibility.Collapsed;
  }

  private void viewChart_Click(object sender, RoutedEventArgs e)
  {
    resultDataGrid.Visibility = System.Windows.Visibility.Collapsed;
    resultGraph.Visibility = System.Windows.Visibility.Visible;
  }
}

MyViewModel.cs

public class MyViewModel : INotifyPropertyChanged
{
  public Dictionary<int, string> Items{ get; set; }
  public IList<DataPoint> Points{ get; set; }

  public void Execute() 
  {
    this.Items = new Dictionary<int, string>();
    this.Points = new List<DataPoint>();

    var randomNumber = GetRandomNumber();
    for (var i=0; i<10; i++) 
    {
      this.Items.Add((i+1), "Item #" + i);

      var dataPoint = new DataPoint(i, (randomNumber*i));
      this.Points.Add(dataPoint);
    }

    NotifyPropertyChanged("Items");
    NotifyPropertyChanged("Points");
  }
}

我的问题是,当用户点击"Execute"按钮时,数据会在 DataGrid 中刷新,这正是我所期待的 . 但是,如果图表首次可见,则只会刷新图表 . 换句话说,如果在 DataGrid 可见时单击"execute",则图表中的绘图点将变为陈旧 . 但是,如果我有 resultGraph 可见,我单击"Execute"点会按预期刷新 . 我不明白我做错了什么 . 任何帮助表示赞赏 .

3 回答

  • 2

    在您的ViewModel中创建

    private int _invalidateFlag = 0;
    public int InvalidateFlag
    {
       get {return _invalidateFlag;}
       set
       {
          _invalidateFlag = value;
          NotifyPropertyChanged();
       }
    }
    
    //and to the end of Execute() add
    
    InvalidateFlag++;
    

    也不要忘记绑定InvalidateFlag

    <oxy:Plot x:Name="resultGraph" InvalidateFlag="{Binding InvalidateFlag}" Background="Transparent" Height="400" HorizontalContentAlignment="Stretch" VerticalAlignment="Stretch" Visibility="Collapsed">
    

    这应该可以解决问题

  • 1

    其实我找到了答案here

    OxyPlot不会观察属性或集合更改 . 这意味着客户端应用程序负责在内容更改时刷新绘图 .

    更改后必须使绘图无效 . 有几个possibilities .

    最简单的可能是一个脏的MVVM:在视图中订阅viewmodel PropertyChanged 事件,检查 Points 上升此事件是否已更改并使绘图无效 .

  • 1

    通常,OxyPlot提供方法 PlotModel.InvalidatePlot(true) 以使用新输入数据刷新图表 . 编辑:哦,我看到你的ViewModel中没有PlotModel属性 . 我的回答需要这样一个属性,它也可以绑定到xaml .

相关问题