【问题标题】:Realtime UI and LiveCharts update in MVVMMVVM 中的实时 UI 和 LiveCharts 更新
【发布时间】:2016-03-22 19:58:02
【问题描述】:

我正在尝试实现一个实时绘图 UI,我正在使用 WPF 与 MVVM 模式和 beto-rodriguez 的实时图表作为我的绘图库,但我在实时更新图表时遇到了一些麻烦.我知道我必须运行多个线程来实时更新 UI,但是我尝试的每一种方法都不起作用(我现在正在学习 C#)。 我很困惑我应该如何正确地实现这个模式以进行实时更新,以及绘图库是否能够做到这一点。

这是我的实际代码(它是我将要做的简化版本,没有实现任何多线程代码)

模型视图代码:

using System;
using System.ComponentModel;
using System.Windows;
using LiveCharts;


    namespace TestMotionDetection
    {
        class MainViewModel : INotifyPropertyChanged
        {
            public SeriesCollection Series { get; set; }

            public Func<double, string> YFormatter { get; set; }
            public Func<double, string> XFormatter { get; set; }

            public DataViewModel SData
            {
                set
                {
                    Series[0].Values.Add(value);
                    OnPropertyChanged("Series");
                }
            }

            public event PropertyChangedEventHandler PropertyChanged;

            public MainViewModel()
            {
                SeriesConfiguration<DataViewModel> config = new SeriesConfiguration<DataViewModel>();
                config.Y(model => model.Value);
                config.X(model => model.Time);

                Series = new SeriesCollection(config)
                {
                    new LineSeries {Values = new ChartValues<DataViewModel>(), PointRadius = 0}
                };

                XFormatter = val => Math.Round(val) + " ms";
                YFormatter = val => Math.Round(val) + " °";
            }

            protected virtual void OnPropertyChanged(string propertyName)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }

            public void generateData()
            {
                DataViewModel val = new DataViewModel();
                for (int i = 0; i < 500; i++)
                {
                    val.Time = i;
                    val.Value = i + 2.3f;
                    SData = val;
                }
            }
        }
    }

查看代码如下:

using System.Windows;


namespace TestMotionDetection
{
    /// <summary>
    /// Logica di interazione per MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private MainViewModel vista;

        public MainWindow()
        {
            vista = new MainViewModel();
            DataContext = vista;
        }

        private void button_Click(object sender, RoutedEventArgs e)
        {
            vista.generateData();
        }
    }
}

还有 XALM:

<Window x:Class="TestMotionDetection.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:lvc="clr-namespace:LiveCharts;assembly=LiveCharts"
        Title="Example 2  (WPF)"
        Width="1025.213"
        Height="482.801">

    <Grid>
        <lvc:LineChart Margin="0,2,245,-2"
                       LegendLocation="Right"
                       Series="{Binding Series}">
            <lvc:LineChart.AxisX>
                <lvc:Axis LabelFormatter="{Binding XFormatter}" Separator="{x:Static lvc:DefaultAxes.CleanSeparator}" />
            </lvc:LineChart.AxisX>
            <lvc:LineChart.AxisY>
                <lvc:Axis LabelFormatter="{Binding YFormatter}" />
            </lvc:LineChart.AxisY>
        </lvc:LineChart>
        <Button x:Name="button"
                Width="151"
                Height="79"
                Margin="804,47,0,0"
                HorizontalAlignment="Left"
                VerticalAlignment="Top"
                Click="button_Click"
                Content="Button" />
    </Grid>
</Window>

[更新 1] []1

【问题讨论】:

标签: c# wpf multithreading mvvm livecharts


【解决方案1】:

您的 XFormatter 和 YFormatter 都应该是这样的:

private Func<double, string> _yFormatter;
public Func<double, string> YFormatter { 
    get{ return _yFormatter; }
    set
    {
        _yFormatter = value;
        OnPropertyChanged("YFormatter");
    }

如果您使用的是 C#6,则应改为使用 nameof(YFormatter)

这将导致视图更新,否则视图无法知道格式化程序已更改。

【讨论】:

  • 问题不在于格式化程序,在我的“主要”实现中,绘图会在数据流结束后更新一秒,而无需我更改格式化程序值。我只在系列中插入新数据。
  • 如果您的格式化程序永远不会改变,那么问题可能与实时图表有关......您没有放在这里的部分代码。从 MVVM 的角度来看,其他一切看起来都很好。我建议您将实时图表添加到您的标签和/或将此问题放在他们的论坛上。
  • ... 或者您每次向系列中添加项目时都需要致电OnPropertyChanged("YFormatter");
  • 我用我的“主要”实现的输出更新了帖子。我不发布它,因为它是我需要修复的垃圾代码。您可以看到格式化程序(标签)已更新。我认为这是一个线程问题
  • 也许我不明白问题出在哪里。您能否说明您期望的结果和得到的结果?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-20
  • 2023-03-08
  • 1970-01-01
  • 2021-08-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多