WPF调用系统自带的Winform Chart控件绘图

最近在研究WPF,需要用到类似Chart的控件来绘制折线图,横坐标自定义时间信息。先后研究了DynamicDataDisplay.ChartPlotter、Toolkit,因为WPF用的人太少了,这方面可以查到的资料太少了。DynamicDataDisplay.ChartPlotter虽然能实现横坐标显示时间,但是我想显示的是历史的时间信息,非当下时间,遂弃之。如果有知道的大神,可以提点下我怎么改。

以上种种,导致我想用熟悉的Winform下的Chart来绘制。

1.首先添加引用

System.Windows.Forms.dll

WindowsFormsIntegration.dll

System.Windows.Forms.DataVisualization.dll

2.xaml添加命名空间

xmlns:wfi="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
xmlns:Chr="clr-namespace:System.Windows.Forms.DataVisualization.Charting;assembly=System.Windows.Forms.DataVisualization"

3.WPF是不可以直接引用WinForm Chart,但可以托管在WindowsFormsHost中使用,所以我们要添加一个宿主容器。

  <WindowsFormsHost x:Name="WFHost_HistoryFlow" Margin="1">
     <Chr:Chart x:Name="Chart_HistoryFlow" GetToolTipText="Chart_HistoryFlow_GetToolTipText" BackColor="WhiteSmoke" MouseWheel="Chart_HistoryFlow_MouseWheel"/>
 </WindowsFormsHost>

4.后台代码.cs添加命名空间

using System.Windows.Forms; using
System.Windows.Forms.DataVisualization.Charting;

5.后台代码

5.1私有变量

   DataTable dataTable = new DataTable();

5.2 初始化

    /// <summary>
    /// 設定Chart Control
    /// </summary>
    private void SetChart()
    {
        ChartArea ca = new ChartArea("ChartArea1");
        this.Chart_HistoryFlow.ChartAreas.Add(ca);
        ChartArea ca_Pres = new ChartArea("ChartArea1");
        this.Chart_HistoryPres.ChartAreas.Add(ca_Pres);
        ChartArea ca_Ratio = new ChartArea("ChartArea1");
        this.Chart_HistoryRatio.ChartAreas.Add(ca_Ratio);

        //Processor
        System.Windows.Forms.DataVisualization.Charting.Legend lgFlow = new System.Windows.Forms.DataVisualization.Charting.Legend("Legend1");
        lgFlow.IsTextAutoFit = true;
        lgFlow.Docking = Docking.Top;
        this.Chart_HistoryFlow.Legends.Add(lgFlow);

        System.Windows.Forms.DataVisualization.Charting.Legend lgPres = new System.Windows.Forms.DataVisualization.Charting.Legend("Legend1");
        lgPres.IsTextAutoFit = true;
        lgPres.Docking = Docking.Top;
        this.Chart_HistoryPres.Legends.Add(lgPres);

        System.Windows.Forms.DataVisualization.Charting.Legend lgRatio = new System.Windows.Forms.DataVisualization.Charting.Legend("Legend1");
        lgRatio.IsTextAutoFit = true;
        lgRatio.Docking = Docking.Top;
        this.Chart_HistoryRatio.Legends.Add(lgRatio);

        SetChartAutoBar(Chart_HistoryFlow);
        SetChartAutoBar(Chart_HistoryPres);
        SetChartAutoBar(Chart_HistoryRatio);
    }

    /// <summary>
    /// 设置折线图游标
    /// </summary>
    private void SetChartAutoBar(Chart chart)
    {
        //设置游标
        chart.ChartAreas[0].CursorX.IsUserEnabled = true;
        chart.ChartAreas[0].CursorX.AutoScroll = true;
        chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
        //设置X轴是否可以缩放
        chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;

        //将滚动内嵌到坐标轴中
        chart.ChartAreas[0].AxisX.ScrollBar.IsPositionedInside = true;
        // 设置滚动条的大小
        chart.ChartAreas[0].AxisX.ScrollBar.Size = 10;
        // 设置滚动条的按钮的风格,下面代码是将所有滚动条上的按钮都显示出来
        chart.ChartAreas[0].AxisX.ScrollBar.ButtonStyle = ScrollBarButtonStyles.All;
        // 设置自动放大与缩小的最小量
        chart.ChartAreas[0].AxisX.ScaleView.SmallScrollSize = double.NaN;
        chart.ChartAreas[0].AxisX.ScaleView.SmallScrollMinSize = 1;
    }    

5.3 事件

    /// <summary>
    /// 历史流量折线图鼠标滚动 滚动条对应滑动 最小及最大数据位置停止
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void Chart_HistoryFlow_MouseWheel(object sender, System.Windows.Forms.MouseEventArgs e)
    {

        //按住Ctrl,缩放
        if ((System.Windows.Forms.Control.ModifierKeys & Keys.Control) == Keys.Control)
        {
            if (e.Delta < 0)
                Chart_HistoryFlow.ChartAreas[0].AxisX.ScaleView.Size += 4;
            else
                Chart_HistoryFlow.ChartAreas[0].AxisX.ScaleView.Size -= 4;
        }
        //不按Ctrl,滚动
        else
        {
            if (e.Delta < 0)
            {
                //当前位置+视图长大于最大数据时停止
                if (Chart_HistoryFlow.ChartAreas[0].AxisX.ScaleView.Position + Chart_HistoryFlow.ChartAreas[0].AxisX.ScaleView.Size < Chart_HistoryFlow.ChartAreas[0].AxisX.ScaleView.ViewMaximum)
                    Chart_HistoryFlow.ChartAreas[0].AxisX.ScaleView.Position += 4;
            }
            else
            {
                //当前位置小于最小数据时停止
                if (Chart_HistoryFlow.ChartAreas[0].AxisX.ScaleView.Position > Chart_HistoryFlow.ChartAreas[0].AxisX.ScaleView.ViewMinimum)
                    Chart_HistoryFlow.ChartAreas[0].AxisX.ScaleView.Position -= 4;
            }

        }
    }

    /// <summary>
    /// 流量脉冲折线图光标显示详细数据
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void Chart_HistoryFlow_GetToolTipText(object sender, System.Windows.Forms.DataVisualization.Charting.ToolTipEventArgs e)
    {
        if (e.HitTestResult.ChartElementType == ChartElementType.DataPoint)
        {
            this.Cursor = System.Windows.Input.Cursors.Cross;
            int i = e.HitTestResult.PointIndex;
            string time = this.dataTable.Rows[i]["时间"].ToString();
            string aFlow = this.dataTable.Rows[i]["A脉冲"].ToString();
            string bFlow = this.dataTable.Rows[i]["B脉冲"].ToString();
            string aPressure = this.dataTable.Rows[i]["A压力"].ToString();
            string bPressure = this.dataTable.Rows[i]["B压力"].ToString();
            string abRatio = this.dataTable.Rows[i]["AB比率"].ToString();
            e.Text = $"时  间:{time}\r\nA脉冲:{aFlow}\r\nB脉冲:{bFlow}\r\nA压力:{aPressure}\r\nB压力:{bPressure}\r\nAB比率:{abRatio}";
        }
        else
        {
            this.Cursor = System.Windows.Input.Cursors.Arrow;
        }
    }

5.4 往Chart中写入数据

    /// <summary>
    /// DataTable数据写入Chart中
    /// </summary>
    /// <param name="dataTable">包含数据的DataTable</param>
    /// <param name="chart">待写入数据的Chart</param>
    public void DataTableToChart(DataTable dataTable, Chart chart,string title, string series1, string series2)
    {
        chart.Series.Clear();   //清空图表中的内容
        chart.Titles.Clear();
        chart.Titles.Add(title);//添加标题
        chart.DataSource = dataTable;

        Series aCodeSeries = chart.Series.Add(series1);//添加第一个表
        aCodeSeries.ChartType = SeriesChartType.Line;//设为折线图显示
        aCodeSeries.YValueMembers = series1;//y轴为数据
        aCodeSeries.XValueMember = "时间";
        Series bCodeSeries = chart.Series.Add(series2);//添加第二个表
        bCodeSeries.ChartType = SeriesChartType.Line;//设为折线图显示
        bCodeSeries.YValueMembers = series2;
    }

往DataTable中写点数据,我的列名为"时间",“A脉冲”,“B脉冲”,“A压力”,“B压力”,“AB比率”。

5.5显示效果

原文链接:https://www.cnblogs.com/stackmiao/p/11463284.html

之前三此发的库http://download.csdn.net/detail/maiker/9621027可以作废,本次为最新的,其中测试了历史曲线的动态显示,这是对Microsoft WpfToolkit的更新和扩展: 1、将库版本升级到.NET 4.6.1,对命名控件进行了替换处理 2、实现了单数据Chart图的混合颜色显示,可通过修改资源字典调整和添加颜色 3、可控制各种Chart图形的数据值显示 4、坐标轴文本可倾斜显示 5、添加了StepLine图和圆环图,圆环半径比例系数可设定,同时添加了饼图的半径比系数,这样可以更好的控制饼图的标签显示,避免重叠 6、Legend可位于区域四侧,对齐方式也可以设定,以及是否显示, 可控制Chart Title是否显示 7、柱状图缝隙间隔可调整 8、全方面的加入了各种加载动画效果,动画效果可屏蔽,同时原系统自带动画效果,可叠加,这是两种不同的效果,可以互补性的单个使用 9、设计了四种主题颜色,各人可以针对图形颜色和背景色进行更好的搭配,在用户项目中,可以自己添加新的主题。 10、扩展了时间轴的应用,在新的DateTimeChart中可以通过鼠标平移和缩放时间轴,并测试了两个例子用于动态显示历史曲线,一个是外部定时更新,一个是内部定时更新 11、对LineDataPoint样式进行了设计,现在可以选择线图的点样式(如空心圆、五角星、三角形,矩形等),同时这些不同的点样式可以体现在Legend上,从而实现颜色和图形的双重区分。 总而言之,微软的控件库做得很标准,还是很好修改的。 最后一直想在历史曲线中取消点动画(及默认的透明度动画),以便提高执行效率,但微软的那部分动画不熟,总是修改失败。 可以发邮件wuyang26@live.cn讨论。
WPF调用WinForm控件是通过将WinForm控件嵌入到WPF内容中实现的。首先,需要在WPF项目中引用`WindowsFormsIntegration`命名空间。 1. 创建WinForm控件:在WinForm项目中创建所需的WinForm控件,例如一个Windows.Forms.Button。 2. 在WPF中添加WindowsFormsHost控件:在WPF的XAML文件中,添加一个WindowsFormsHost控件。 ```xaml <Grid> <WindowsFormsHost Name="windowsFormsHost1" /> </Grid> ``` 3. 将WinForm控件添加到WindowsFormsHost控件中:在WPF的代码文件中,在相关的事件处理程序或页面加载完成等事件中,将WinForm控件添加到WindowsFormsHost控件中。 ```csharp private void Window_Loaded(object sender, RoutedEventArgs e) { System.Windows.Forms.Button winFormButton = new System.Windows.Forms.Button(); windowsFormsHost1.Child = winFormButton; } ``` 通过以上步骤,就可以将WinForm控件嵌入到WPF中了。需要注意的是,由于WPFWinForm使用了不同的UI渲染技术,嵌入的WinForm控件的外观可能会与周围的WPF控件不完全一致,需要进行一些样式调整来保持一致性。 同时,还可以通过WPF的命令模型和事件模型与嵌入的WinForm控件进行交互。例如,可以通过WPF的命令绑定和事件处理程序来响应WinForm控件的点击事件,实现业务逻辑的处理。 总而言之,通过WindowsFormsHost控件可以在WPF中嵌入WinForm控件,并通过WPF的命令和事件模型来与其进行交互,提供更丰富的用户界面和功能。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值