将OxyPlot封装成用户控件后在WPF中的应用

这篇具有很好参考价值的文章主要介绍了将OxyPlot封装成用户控件后在WPF中的应用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、文件架构
将OxyPlot封装成用户控件后在WPF中的应用,wpf
2、加载依赖项
Newtonsoft.Json
OxyPlot.Wpf
3、NotifyBase.cs

namespace Accurate.Common
{
    public class NotifyBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler? PropertyChanged;
        public void DoNotify([CallerMemberName] string prppertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prppertyName));
        }
    }
}

4、CartesianChartViewModel.cs

namespace Accurate.Controls.ViewModels
{
    public class CartesianChartViewModel:NotifyBase
    {
		/// <summary>
		/// 定义plot属性
		/// </summary>
		private PlotModel? plotModel;

		public PlotModel? PlotModel
        {
			get { return plotModel; }
			set { plotModel = value; this.DoNotify(); }
		}
		/// <summary>
		/// 构造函数
		/// </summary>
		public CartesianChartViewModel()
		{
            PlotModel=new PlotModel();
        }
    }
}

5、CartesianChart.xaml

<UserControl x:Class="Accurate.Controls.CartesianChart"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Accurate.Controls"
             xmlns:oxy="http://oxyplot.org/wpf"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Border Name="Layout" BorderBrush="#DDD" BorderThickness="1" CornerRadius="10" Background="LightBlue">
        <Border.Effect>
            <DropShadowEffect Color="#F2F2F2" ShadowDepth="10" BlurRadius="10" Opacity="0.4" Direction="270"/>
        </Border.Effect>
        <oxy:PlotView x:Name="PlotView" Model="{Binding Path= PlotModel}"></oxy:PlotView>
    </Border>
</UserControl>

6、CartesianChart.xaml.cs

namespace Accurate.Controls
{
    /// <summary>
    /// CartesianChart.xaml 的交互逻辑
    /// </summary>
    public partial class CartesianChart : UserControl
    {
        //Plot
        public CartesianChartViewModel? viewModel;
        //曲线数组
        public LineSeries[] lineSeries;
        /// <summary>
        /// 曲线属性设置属性
        /// </summary>
        public string ChartSetStr
        {
            get { return (string)GetValue(ChartSetStrProperty); }
            set { SetValue(ChartSetStrProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ChartSetStrProperty =
            DependencyProperty.Register("ChartSetStr", typeof(string), typeof(CartesianChart), 
                new PropertyMetadata(default(string),new PropertyChangedCallback(OnSetPropertyChanged)));
        /// <summary>
        /// 设置改变处理
        /// </summary>
        /// <param name="d"></param>
        /// <param name="e"></param>
        private static void OnSetPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if(d is CartesianChart)
            {
                CartesianChart chart = (CartesianChart)d;
                chart.CreatePlot();
            }
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        public CartesianChart()
        {
            InitializeComponent();
            this.Loaded += CartesianChart_Loaded;
            Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;
        }
        /// <summary>
        /// 退出时释放资源
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Dispatcher_ShutdownStarted(object? sender, EventArgs e)
        {
            //timer?.Stop();
        }
        /// <summary>
        /// 控件加载
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CartesianChart_Loaded(object sender, RoutedEventArgs e)
        {
            CreatePlot();
        }
        /// <summary>
        /// 获取轴名称
        /// </summary>
        /// <param name="axisType"></param>
        /// <returns></returns>
        private string GetAxisKey(AxisType axisType)
        {
            string str = "";
            switch (axisType)
            {
                case AxisType.X:
                    str = "x";
                    break;
                case AxisType.Y:
                    str = "y";
                    break;
                case AxisType.X1:
                    str = "x1";
                    break;
                case AxisType.Y1:
                    str = "y1";
                    break;
            }
            return str;
        }
        /// <summary>
        /// 轴设置
        /// </summary>
        /// <param name="axisItemModels"></param>
        private void LinearAxisSet(ObservableCollection<AxisItemModel> axisItemModels)
        {
            if(axisItemModels != null && axisItemModels.Count > 1)
            {
                for(int i = 0; i < axisItemModels.Count; i++)
                {
                    var axis = new LinearAxis();
                    //设置轴类型
                    axis.Title = axisItemModels[i].Name;
                    axis.Key = GetAxisKey(axisItemModels[i].Type);
                    axis.Position = axisItemModels[i].Position;
                    //axis.Minimum = axisItemModels[i].Minimum;
                    //axis.MajorStep = axisItemModels[i].Step;
                    //axis.Maximum = axisItemModels[i].Maximum;
                    viewModel?.PlotModel?.Axes.Add(axis);
                }
            }
        }
        /// <summary>
        /// 曲线设置
        /// </summary>
        /// <param name="curveItemModels"></param>
        private void LineSeriesSet(ObservableCollection<CurveItemModel> curveItemModels)
        {
            if(curveItemModels != null && curveItemModels.Count > 1)
            {
                lineSeries = new LineSeries[curveItemModels.Count];
                for (int i=0;i<curveItemModels.Count;i++)
                {
                    lineSeries[i]=new LineSeries();
                    lineSeries[i].Title = curveItemModels[i].Name;
                    lineSeries[i].YAxisKey = GetAxisKey(curveItemModels[i].Type);
                    lineSeries[i].Color = GetOxyColor(curveItemModels[i].ItemColor);
                    lineSeries[i].MarkerType = curveItemModels[i].MarkType;
                    lineSeries[i].MarkerStroke = GetOxyColor(curveItemModels[i].MarkStroke);
                    lineSeries[i].MarkerSize = curveItemModels[i].MarkSize;
                    viewModel?.PlotModel.Series.Add(lineSeries[i]);
                }
            } 
        }
        private List<ChartData> GetChartData()
        {
            var data=new List<ChartData>()
            {
                new ChartData{Date=DateTime.Now.Date.AddDays(-10),Data1=120,Data2=20},
                new ChartData{Date=DateTime.Now.Date.AddDays(-8),Data1=100,Data2=80},
                new ChartData{Date=DateTime.Now.Date.AddDays(-6),Data1=60,Data2=100},
                new ChartData{Date=DateTime.Now.Date.AddDays(-4),Data1=100,Data2=70},
                new ChartData{Date=DateTime.Now.Date.AddDays(-2),Data1=50,Data2=90}
            };
            return data;
        }
        private void LineSeriesDataSourceSet(List<ChartData> list)
        {
            for(int i=0;i<2;i++)
            {
                lineSeries[i].ItemsSource = list;
                lineSeries[i].DataFieldX = "Date";
                lineSeries[i].DataFieldY = "Data" + i;
                viewModel?.PlotModel.Series.Add(lineSeries[i]);
            }
        }
        /// <summary>
        /// 颜色转换
        /// </summary>
        /// <param name="color"></param>
        /// <returns></returns>
        private OxyColor GetOxyColor(string color)
        {
            OxyColor oxyColor= OxyColors.Black;
            switch(color)
            {
                case "Black":
                    oxyColor = OxyColors.Black;
                    break;
                case "Red":
                    oxyColor = OxyColors.Red;
                    break;
                case "Blue":
                    oxyColor = OxyColors.Blue;
                    break;
                case "Green":
                    oxyColor = OxyColors.Green;
                    break;
                case "Yellow":
                    oxyColor = OxyColors.Yellow;
                    break;
                case "Violet":
                    oxyColor = OxyColors.Violet;
                    break;
            }
            return oxyColor;
        }
        /// <summary>
        /// Chart设置
        /// </summary>
        private void CreatePlot()
        {
            if (ChartSetStr == null) return;
            ChartSetModel ChartSet=JsonConvert.DeserializeObject<ChartSetModel>(ChartSetStr);
            //曲线设置
            viewModel = new CartesianChartViewModel();
            PlotView.DataContext = viewModel;
            viewModel.PlotModel.Title = ChartSet.Name;
            viewModel.PlotModel.Legends.Add(new Legend
            {
                LegendPlacement = LegendPlacement.Outside,
                LegendPosition = LegendPosition.BottomCenter,
                LegendOrientation = LegendOrientation.Horizontal,
                LegendBorderThickness = 0,
                LegendTextColor = OxyColors.LightGray
            });
            LinearAxisSet(ChartSet.AxisItemModels);
            LineSeriesSet(ChartSet.CurveItemModels);
            //LineSeriesDataSourceSet(GetChartData());
        }
    }
}

7、AxisItemModel.cs

namespace Accurate.Model
{
    /// <summary>
    /// 曲线设置类
    /// </summary>
    public class ChartSetModel
    {
        public string Name { get; set; } = "曲线示例";
        public ObservableCollection<AxisItemModel> AxisItemModels { get; set; }=new ObservableCollection<AxisItemModel>();
        public ObservableCollection<CurveItemModel> CurveItemModels { get; set; } = new ObservableCollection<CurveItemModel>();
    }
    /// <summary>
    /// 坐标轴设置
    /// </summary>
    public class AxisItemModel
    {
        public string Name { get; set; } = "X";
        public AxisType Type { get; set; } = 0;
        public AxisPosition Position { get; set; } = AxisPosition.Bottom;
        public double Minimum { get; set; } = 0;
        public double Step { get; set; } = 1;
        public double Maximum { get; set; } = 100;
    }
    /// <summary>
    /// 曲线设置
    /// </summary>
    public class CurveItemModel
    {
        public string Name { get; set; } = "时间";
        public AxisType Type { get; set; } = 0;
        public string ItemColor { get; set; } = "Black";
        public MarkerType MarkType { get; set; } = MarkerType.Circle;
        public string MarkStroke { get; set; } = "Black";
        public double MarkSize { get; set; } = 3;
    }
    /// <summary>
    /// 枚举轴类型
    /// </summary>
    public enum AxisType:int
    {
        X,Y,X1,Y1
    }
    /// <summary>
    /// 数据Item(单点数据添加)
    /// </summary>
    public class DataItem
    {
        public double DataX { get; set; }
        public List<double> DataYs { get; set; }=new List<double>();
    }
    public class ChartData
    {
        public DateTime Date { get; set; }
        public double Data1 { get; set; }
        public double Data2 { get; set; }
    }
}

8、MainWindowViewModel。cs

namespace Accurate.ViewModel
{
    public class MainWindowViewModel:NotifyBase
    {
		private string chartSetString;

		public string ChartSetString
		{
			get { return chartSetString; }
			set { chartSetString = value;this.DoNotify(); }
		}
        public ChartSetModel ChartSetData { get; set; } = new ChartSetModel();
        

        public MainWindowViewModel()
		{
            RefreshChartSet();
            
        }
		private void RefreshChartSet()
		{
            ChartSetData.Name = "正弦和余弦曲线";
            //设置坐标轴
            ChartSetData.AxisItemModels.Add(
                new AxisItemModel() { Name = "X", Type = AxisType.X, Position = OxyPlot.Axes.AxisPosition.Bottom, Minimum = 0, Step = 1, Maximum = 200 }
            );
            ChartSetData.AxisItemModels.Add(
                new AxisItemModel() { Name = "Y", Type = AxisType.Y, Position = OxyPlot.Axes.AxisPosition.Left, Minimum = -10, Step = 1, Maximum = 10 }
            );
            //设置曲线
            ChartSetData.CurveItemModels.Add(new CurveItemModel
            {
                Name = "正弦曲线",
                Type = AxisType.Y,
                ItemColor = "Red",
                MarkType = MarkerType.Circle,
                MarkStroke = "Blue",
                MarkSize = 3
            });
            ChartSetData.CurveItemModels.Add(new CurveItemModel
            {
                Name = "余弦曲线",
                Type = AxisType.Y,
                ItemColor = "Green",
                MarkType = MarkerType.Square,
                MarkStroke = "Yellow",
                MarkSize = 3
            });
            ChartSetString = JsonConvert.SerializeObject(ChartSetData);
        }

    }
}

9、MainWindow.xaml

<Window x:Class="Accurate.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Accurate"
        xmlns:controls="clr-namespace:Accurate.Controls"
        mc:Ignorable="d"
        Title="MainWindow" Height="600" Width="800">
    <Grid>
        <controls:CartesianChart x:Name="Cartesian" ChartSetStr="{Binding ChartSetString}"  Height="450" Width="800" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
</Window>

10、MainWindow.xaml.cs文章来源地址https://www.toymoban.com/news/detail-539250.html

namespace Accurate
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private DispatcherTimer? timer;
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new MainWindowViewModel();
            //this.Cartesian.lineSeries
            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(100);
            timer.Tick += TimerTick;
            timer.Start();
        }
        double x = 0;
        /// <summary>
        /// 定时更新数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TimerTick(object? sender, EventArgs e)
        {
            double y = 10 * Math.Sin(x / 10.0);
            this.Cartesian.lineSeries[0]?.Points.Add(new DataPoint(x, y));
            double y1 = 10 * Math.Cos(x / 10.0);
            this.Cartesian.lineSeries[1]?.Points.Add(new DataPoint(x, y1));
            x++;
            if (this.Cartesian.lineSeries[0]?.Points.Count > 200)
            {
                this.Cartesian.lineSeries[0].Points.RemoveAt(0);
            }
            if (this.Cartesian.lineSeries[1]?.Points.Count > 200)
            {
                this.Cartesian.lineSeries[1].Points.RemoveAt(0);
            }
            this.Cartesian.viewModel?.PlotModel.InvalidatePlot(true);
        }
    }
}

到了这里,关于将OxyPlot封装成用户控件后在WPF中的应用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • WPF 用户控件依赖注入赋值

    我一直想组件化得去开发WPF,因为我觉得将复杂问题简单化是最好的 cs部分 我将复杂的依赖注入的代码进行了优化,减少了重复内容的输入。 我现在依赖属性扩展封装在一个静态文件里面 记得UserControl.xaml里面绑定你ViewModel。这样的话有代码提示 我后面要根据Vue的单向数据

    2024年02月07日
    浏览(44)
  • 如何使用 WPF 用户控件关闭父窗口

    How to close parent windows using WPF User Control 如何使用 WPF 用户控件关闭父窗口 【问题描述】 假设有两个WPF窗口:window1和window2。 window1有一个按钮,单击此按钮将打开window2。window2包含一个用户控件。此用户控件有一个用于关闭window2的按钮。 怎样才能实现这个场景呢? 【解决方案

    2024年02月15日
    浏览(43)
  • 使用WPF开发自定义用户控件,以及实现相关自定义事件的处理

    在前面随笔《使用Winform开发自定义用户控件,以及实现相关自定义事件的处理》中介绍了Winform用户自定义控件的处理,对于Winform自定义的用户控件来说,它的呈现方式主要就是基于GDI+进行渲染的,对于数量不多的控件呈现,一般不会觉察性能有太多的问题,随着控件的数量

    2024年02月02日
    浏览(52)
  • WPF实现html中的table控件

    前言 相信很多做WPF开发的小伙伴都遇到过表格类的需求,虽然现有的Grid控件也能实现,但是使用起来的体验感并不好,比如要实现一个Excel中的表格效果,估计你能想到的第一个方法就是套Border控件,用这种方法你需要控制每个Border的边框,并且在一堆Bordr中找到Grid.Row,G

    2024年03月26日
    浏览(44)
  • 【WPF应用39】WPF 控件深入解析:SaveFileDialog 的属性与使用方法

    在 Windows Presentation Foundation (WPF) 中,SaveFileDialog 控件是一个非常重要的文件对话框,它允许用户在文件系统中选择一个位置以保存文件。这个控件提供了很多属性,可以自定义文件对话框的显示内容和行为。 本文将详细介绍 SaveFileDialog 控件的属性和功能,如何在 WPF 应用程序

    2024年04月12日
    浏览(50)
  • 在WPF应用中使用GongSolutions.WPF.DragDrop实现列表集合控件的拖动处理

    WPF应用中,控件本身也可以通过实现事件代码实现拖动的处理,不过如果我们使用GongSolutions.WPF.DragDrop来处理,事情会变得更加简单轻松,它支持很多控件的拖动处理,如ListBox, ListView, TreeView, DataGrid等源自ItemsControl的控件,本篇随笔介绍在工作流模块中拖动TreeView和DataGrid列表

    2024年02月05日
    浏览(41)
  • WPF应用开发之控件动态内容展示

    在我们开发一些复杂信息的时候,由于需要动态展示一些相关信息,因此我们需要考虑一些控件内容的动态展示,可以通过动态构建控件的方式进行显示,如动态选项卡展示不同的信息,或者动态展示一个自定义控件的内容等等,目的就是能够减少一些硬编码的处理方式,以

    2024年02月05日
    浏览(62)
  • 【wpf 应用6】基本控件-Label的详解与示例

    在WPF中,Label控件主要用于显示文本信息,通常用于作为其他控件的说明或者展示数据。Label控件本身不支持交互,它仅用于展示目的。与TextBlock控件相比,Label控件提供了一些特定的样式和行为,使其更适合作为说明性文本使用。 Label控件拥有多种属性,以下是一些常用的属

    2024年03月25日
    浏览(61)
  • WPF嵌入外部exe应用程序-使用Winfom控件承载外部程序

    首先要解决在WPF中如何使用Winfom控件的问题,官方对此有支持的方式。 在引用管理器中添加winfrom相关的程序集 System.Windows.Forms 和 WindowsFormsIntegration 。 然后使用winform的控件,得在外面套一层WindowsFormsHost(好像添加了WindowsFormsIntegration,不使用wfi:也能使用) 这样就可以在WPF中使

    2024年02月17日
    浏览(66)
  • 界面控件DevExpress WPF属性网格 - 让应用轻松显示编辑各种属性事件

    DevExpress WPF Property Grid(属性网格)灵感来自于Visual Studio,Visual Studio启发的属性窗口(对象检查器)让在WPF应用程序显示和编辑任何对象的属性和事件变得更容易! P.S :DevExpress WPF拥有120+个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress

    2024年01月18日
    浏览(66)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包