首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >WPF/C#:用LiveCharts RowSeries更新OnPropretyChanged

WPF/C#:用LiveCharts RowSeries更新OnPropretyChanged
EN

Stack Overflow用户
提问于 2022-09-25 03:16:50
回答 1查看 88关注 0票数 1

我在一个ViewModel中有一个水平条形图,显示过去6或12个月前10位客户(默认6)。当用户单击按钮时,我希望数据切换到6或12个月。我只是想不出怎么才能让图表更新。我已经实现了INotifyPropertyChanged接口,但我肯定做错了。我读过关于这个主题的多篇文章:仍然不知道出了什么问题。

图表屏幕截图

ReportClientModel

代码语言:javascript
运行
复制
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace ReportXpress.Models
{
    public class ReportClientModel : INotifyPropertyChanged
    {
        private string name;
        public string Name 
        {
            get => this.name; 
            set
            {
                this.name = value;
                OnPropertyChanged();
            }
        }
        public double? sales;
        public double? Sales 
        {
            get => this.sales;
            set
            {
                this.sales = value;
                OnPropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName=null)
        {
            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

ViewModelBase

代码语言:javascript
运行
复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;

namespace ReportXpress.ViewModels
{
    // Abstract : can only be used via inheritance
    public abstract class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler? PropertyChanged;

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

ClientViewModel

代码语言:javascript
运行
复制
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using SkiaSharp;
using System.Collections.ObjectModel;
using System.Drawing;
using LiveChartsCore.Defaults;
using ReportXpress.Models;
using ReportXpress.Repositories;
using Org.BouncyCastle.Tls;
using System.Windows.Input;
using System.ComponentModel;

namespace ReportXpress.ViewModels
{
    public class ClientViewModel : ViewModelBase
    {
        //Fields
        private ObservableCollection<ISeries> clientsSalesSeries;
        public ReportClientModel[] topClients6Months;
        public ReportClientModel[] topClients12Months;

        //Properties
        public ObservableCollection<ISeries> ClientsSalesSeries 
        { get 
            {
                return clientsSalesSeries; 
            } 
            set
            {
                clientsSalesSeries = value;
                OnPropertyChanged(nameof(ClientsSalesSeries));
            }
        }
        public string[] Labels { get; set; }
        public LiveChartsCore.Measure.Margin Margin { get; set; } = new LiveChartsCore.Measure.Margin(25,0,150,50);

        //Events
        public new event PropertyChangedEventHandler PropertyChanged;

        //--> Commands
        public ICommand ShowLast6Months { get; }
        public ICommand ShowLast12Months { get; }
        
        public ClientViewModel()
        {
            //Initialize commands
            ShowLast6Months = new ViewModelCommand(ExecuteShowLast6Months);
            ShowLast12Months = new ViewModelCommand(ExecuteShowLast12Months);

            topClients6Months = new ReportClientModel[]
            {
                new ReportClientModel { Name = "Client 10 name", Sales=30689 },
                new ReportClientModel { Name = "Client 9 name", Sales=31558 },
                new ReportClientModel { Name = "Client 8 name", Sales=38937 },
                new ReportClientModel { Name = "Client 7 name", Sales=42139 },
                new ReportClientModel { Name = "Client 6 name", Sales=49860 },
                new ReportClientModel { Name = "Client 5 name", Sales=51561 },
                new ReportClientModel { Name = "Client 4 name", Sales=69554 },
                new ReportClientModel { Name = "Client 3 name", Sales=70524 },
                new ReportClientModel { Name = "Client 2 name", Sales=276170 },
                new ReportClientModel { Name = "Client 1 name", Sales=345835 }
            };

            topClients12Months = new ReportClientModel[]
{
                new ReportClientModel { Name = "Client 10 name", Sales=56664 },
                new ReportClientModel { Name = "Client 9 name", Sales=79135 },
                new ReportClientModel { Name = "Client 8 name", Sales=80280 },
                new ReportClientModel { Name = "Client 7 name", Sales=83675 },
                new ReportClientModel { Name = "Client 6 name", Sales=92612 },
                new ReportClientModel { Name = "Client 5 name", Sales=126429 },
                new ReportClientModel { Name = "Client 4 name", Sales=158313 },
                new ReportClientModel { Name = "Client 3 name", Sales=163430 },
                new ReportClientModel { Name = "Client 2 name", Sales=442796 },
                new ReportClientModel { Name = "Client 1 name", Sales=592028 }
};
            //Default values : last 6 months
            ExecuteShowLast6Months(null);

            Formatter = value => value.ToString("0") + " k$";
        }

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

        private void ExecuteShowLast12Months(object obj)
        {
            ClientsSalesSeries = new ObservableCollection<ISeries>
            {
                new RowSeries<ReportClientModel>
                {
                    Values = topClients12Months,
                    Mapping = (client, point) =>
                    {
                        // use the Sales property in this series
                        point.PrimaryValue = (float)client.Sales;
                        // use the Index of the item
                        point.SecondaryValue = point.Context.Entity.EntityIndex;
                    },
                    Fill = new SolidColorPaint(SKColors.SkyBlue),
                    TooltipLabelFormatter = (point) => point.PrimaryValue.ToString("C2"),
                    DataLabelsPaint = new SolidColorPaint(SKColors.White),
                    DataLabelsSize = 14,
                    DataLabelsPosition = LiveChartsCore.Measure.DataLabelsPosition.End,
                    DataLabelsFormatter = (point) => topClients6Months[point.Context.Entity.EntityIndex].Name,
                }
            };
        }

        private void ExecuteShowLast6Months(object obj)
        {
            ClientsSalesSeries = new ObservableCollection<ISeries>
            {
                new RowSeries<ReportClientModel>
                {
                    Values = topClients6Months,
                    Mapping = (client, point) =>
                    {
                        // use the Sales property in this series
                        point.PrimaryValue = (float)client.Sales;
                        // use the Index of the item
                        point.SecondaryValue = point.Context.Entity.EntityIndex;
                    },
                    Fill = new SolidColorPaint(SKColors.SkyBlue),
                    TooltipLabelFormatter = (point) => point.PrimaryValue.ToString("C2"),
                    DataLabelsPaint = new SolidColorPaint(SKColors.White),
                    DataLabelsSize = 14,
                    DataLabelsPosition = LiveChartsCore.Measure.DataLabelsPosition.End,
                    DataLabelsFormatter = (point) => topClients6Months[point.Context.Entity.EntityIndex].Name,
                }
            };
        }

        public Axis[] XAxesAmounts { get; set; } =
        {
            new Axis
            {
                LabelsPaint = new SolidColorPaint{ Color= SKColors.White},
                Labeler = Labelers.Currency,
                NameTextSize=10,
                ShowSeparatorLines=true,
                SeparatorsPaint = new SolidColorPaint { Color = SKColor.Parse("#33ffffff")},
                TextSize=10
            }
        };

        public Axis[] YAxesClients { get; set; } =
        {
            new Axis
            {
                Name = "",
                NamePaint = new SolidColorPaint{ Color=SKColors.White},
                LabelsPaint = new SolidColorPaint{ Color= SKColors.White},
                Labeler = null,
                IsVisible = true,
                NameTextSize=10,
                LabelsRotation=0,
                ShowSeparatorLines = false,
                MinLimit=-0.5,
                TextSize=10
            }

        };
    }
}

ClientView (只有图表部分)

代码语言:javascript
运行
复制
                <!--Chart for Top Clients-->
                <lvc:CartesianChart Grid.Row="1" Margin="0,0,0,15"
                                    Name="chartClientSales"
                                    Series="{Binding ClientsSalesSeries}"
                                    XAxes="{Binding XAxesAmounts}"
                                    YAxes="{Binding YAxesClients}"
                                    DrawMargin="{Binding Margin}"
                                    TooltipPosition="Right"
                                    ZoomMode="Both"
                                    />

ExecuteShowLast12Months中添加断点可以确认该系列中的数据被更改,但图表没有更新以反映新的数据。我做错了什么?我还没有看到在RowSeries中使用自定义类的其他帖子。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-25 04:10:36

你有两个选择

  1. 通过清除ObservableCollection并直接向其添加新数据来更新本系列(这样您就不必实现INotifyPropertyChanged)
代码语言:javascript
运行
复制
public ObservableCollection<ISeries> ClientsSalesSeries {set; get;} = new();
// ...
private void ExecuteShowLast12Months(object obj)
{
    ClientsSalesSeries.Clear();
    ClientsSalesSeries.Add(new RowSeries<ReportClientModel>{ });
}
// ...
private void ExecuteShowLast6Months(object obj)
{
    ClientsSalesSeries.Clear();
    ClientsSalesSeries.Add(new RowSeries<ReportClientModel>{ });
}
  1. Series的绑定模式设置为TwoWay (可以使用任何集合,例如。(名单)
代码语言:javascript
运行
复制
Series="{Binding ClientsSalesSeries, Mode=TwoWay}"

如果您想要从ObservableCollection中获益,最好选择第一个选项。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73841847

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档