我不知不觉地获取数据并尝试通过LineSeries填充绘图,除非更新绑定集合(ObservableCollection)时绘图不会刷新。注意:当绑定集合发生更改时,我有一个XAML行为来调用InvalidatePlot(true)。
有人可以解释为什么情节没有按预期更新吗?
WPF .Net 4.0 OxyPlot 2014.1.293.1
我有以下XAML数据窗口,因为您可以看到LineSeries ItemsSource绑定到ViewModel中的属性(PlotData):
<DataTemplate DataType="{x:Type md:DataViewModel}">
<Grid>
<oxy:Plot x:Name="MarketDatePlot"
Margin="10">
<oxy:Plot.Axes>
<oxy:DateTimeAxis Position="Bottom"
StringFormat="dd/MM/yy"
MajorGridlineStyle="Solid"
MinorGridlineStyle="Dot"
IntervalType="Days"
IntervalLength="80" />
<oxy:LinearAxis Position="Left"
MajorGridlineStyle="Solid"
MinorGridlineStyle="Dot"
IntervalLength="100" />
</oxy:Plot.Axes>
<oxy:LineSeries ItemsSource="{Binding Path=PlotData, Mode=OneWay}" />
<i:Interaction.Behaviors>
<behaviors:OxyPlotBehavior ItemsSource="{Binding Path=PlotData, Mode=OneWay}" />
</i:Interaction.Behaviors>
</oxy:Plot>
</Grid>
</DataTemplate>
正如我所说,ViewModel以异步方式请求并填充绑定集合(绑定集合的实际填充发生在UI线程上):
public sealed class DataViewModel : BaseViewModel, IDataViewModel
{
private readonly CompositeDisposable _disposable;
private readonly CancellationTokenSource _cancellationTokenSource;
private readonly RangeObservableCollection<DataPoint> _plotData;
public DataViewModel(DateTime fromDate, DateTime toDate, IMarketDataService marketDataService, ISchedulerService schedulerService)
{
_plotData = new RangeObservableCollection<DataPoint>();
_disposable = new CompositeDisposable();
if (fromDate == toDate)
{
// nothing to do...
return;
}
_cancellationTokenSource = new CancellationTokenSource();
_disposable.Add(Disposable.Create(() =>
{
if (!_cancellationTokenSource.IsCancellationRequested)
{
_cancellationTokenSource.Cancel();
}
}));
marketDataService.GetDataAsync(fromDate, toDate)
.ContinueWith(t =>
{
if (t.IsFaulted)
{
throw new Exception("Failed to get market data!", TaskHelper.GetFirstException(t));
}
return t.Result.Select(x => new DataPoint(DateTimeAxis.ToDouble(x.Time), x.Value));
}, schedulerService.Task.Default)
.SafeContinueWith(t => _plotData.AddRange(t.Result), schedulerService.Task.CurrentSynchronizationContext);
}
public void Dispose()
{
_disposable.Dispose();
}
public IEnumerable<DataPoint> PlotData
{
get { return _plotData; }
}
}
XAML行为如下所示:
(我似乎无法再粘贴代码,因此保存时会出现错误)
答案 0 :(得分:4)
添加数据时,OxyPlot不会自动更新。
您必须调用plotname.InvalidatePlot(true);
它必须在UI调度程序线程上运行,即
Dispatcher.InvokeAsync(() =>
{
plotname.InvalidatePlot(true);
}
答案 1 :(得分:2)
不知道人们是否仍然需要这个但是我遇到了与itemsource没有更新图表相同的问题。现有的解决方案都没有帮助我。
好吧,我终于找到了整个事情无效的原因。在我实际初始化它之前,我已将我的集合分配给itemsource(新的Observable ....)。
当我尝试将已初始化的集合分配给我的itemsource时,整个过程开始工作。
希望这有助于某人。
答案 2 :(得分:2)
我知道这是一个老问题,但也许有人会在经过数小时的双重检查后使用我的答案。我使用MVVM。 我通过等待Task.Run(()=&gt; update())来更新数据;那并没有在我的UI中呈现我的情节。我在设置它之前也在初始化我的PlotModel。 事实证明,初始化该update()方法中的PlotModel并没有在我的UI中注册。在我调用该任务之前,我必须初始化它。
public ViewModel()
{
Plot = new PlotModel(); //(Plot is a property using
// INotifyPropertyChanged)
PlotGraph = new RelayCommand(OnPlotGraph);
}
public RelayCommand PlotGraph {get; set;}
private async void OnPlotGraph()
{
await Task.Run(() => Update());
}
private void Update()
{
var tempPlot = new PlotModel();
//(set up tempPlot, add data to tempPlot)
Plot = tempPlot;
}