none
Chart上にテキストボックスの貼り付け RRS feed

  • 質問

  • Chartコントロールのグラフ上に付箋紙のようなメモ書きを表示させるWPFコントロールを作成しています。
    ToolTipは別アプリに切り替えた場合にそのアプリより前面に表示されてしまうため、使用できず。
    テキストボックスを貼り付けてみたのですが、グラフ表示が上にきてしまい、テキストボックスを表示することができません。
    Panel.ZIndexの設定しても、グラフ表示が上にきてしまいます。
    Chartコントロールより前面に別コントロールを表示させる方法はありますでしょうか。

    やりたいこと
     Chartコントロールのグラフ上、マウスクリックされた位置にテキストボックスを貼り付ける
     テキストボックスに任意の文字列を入力し、入力文字に応じてテキストボックスのサイズを変更する
     テキストボックスをマウスで移動させる
     テキストボックスを右クリックでポップアップメニューを出し、削除できるようにする

    環境
     Visual Studio 2013
     .NET Framework 3.5
     C#
     Microsoft Chart Controls for Microsoft .NET Framework 3.5使用
    2021年2月12日 4:16

すべての返信

  • Chart.Controls.Addで追加すれば常に前になります

    namespace WindowsFormsApplication1
    {
        using System;
        using System.Drawing;
        using System.Windows.Forms;
        using System.Windows.Forms.DataVisualization.Charting;
    
        public partial class Form1 : Form
        {
            private Chart chart;
    
            public Form1()
            {
                InitializeComponent();
    
                this.Controls.Clear();
                AddChart();
    
                this.chart.Click += chart_Click;
            }
    
            private void chart_Click(object sender, EventArgs e)
            {
                if ((Control.ModifierKeys != Keys.Shift))
                {
                    //シフトキーが押されている場合のみTextBoxを追加する
                    return;
                }
    
                TextBox txb = new TextBox();
                txb.TextChanged += txb_TextChanged;
                txb.LostFocus += txb_LostFocus;
                txb.MouseDown += txb_MouseDown;
    
                txb.BackColor = Color.Yellow;
                txb.ForeColor = Color.Black;
                txb.Multiline = true;
                txb.BorderStyle = BorderStyle.None;
                txb.MinimumSize = new Size(10, txb.Height);
                txb.Width = 10;
                txb.Text = "";
    
                var pos = System.Windows.Forms.Cursor.Position;
                pos = this.chart.PointToClient(pos);
    
                txb.Left = pos.X;
                txb.Top = pos.Y;
    
                this.chart.Controls.Add(txb); //chartの子としてTextBoxを追加
                txb.Focus();
            }
    
            private Point posMouseDown;
            private Point posStart;
            private void txb_MouseDown(object sender, MouseEventArgs e)
            {
                var txb = (TextBox)sender;
    
                if (e.Button == MouseButtons.Right)
                {
                    //コンテキストメニュー表示
                    ContextMenuStrip contextMenu = new ContextMenuStrip();
                    contextMenu.Closed += (s2, e2) =>
                    {
                        txb.ContextMenuStrip = null;
                    };
    
                    var mi = contextMenu.Items.Add("テキストボックス削除");
                    mi.Click += (s2, e2) =>
                    {
                        txb.Parent.Controls.Remove(txb);
                    };
                    contextMenu.Items.Add(new ToolStripSeparator());
                    mi = contextMenu.Items.Add("コピー");
                    mi.Click += (s2, e2) => { txb.Copy(); };
    
                    mi = contextMenu.Items.Add("貼り付け");
                    mi.Click += (s2, e2) => { txb.Paste(); };
    
                    mi = contextMenu.Items.Add("切り取り");
                    mi.Click += (s2, e2) => { txb.Cut(); };
    
                    txb.ContextMenuStrip = contextMenu;
                    txb.ContextMenuStrip.Show(e.Location);
                }
                else if (e.Button == MouseButtons.Left && Control.ModifierKeys == Keys.Alt)
                {
    
                    //Altキーを押しながらマウスダウンで移動開始
                    txb.Cursor = Cursors.SizeAll;
                    txb.Capture = true;
                    txb.MouseMove += txb_MouseMove;
                    txb.MouseUp += txb_MouseUp;
    
                    posStart = txb.Location;
                    posMouseDown = txb.Parent.PointToClient(System.Windows.Forms.Cursor.Position);
                }
            }
    
            private void txb_MouseMove(object sender, MouseEventArgs e)
            {
                var txb = (TextBox)sender;
    
                var newPos = txb.Parent.PointToClient(System.Windows.Forms.Cursor.Position);
                var diff = new Point(newPos.X - posMouseDown.X, newPos.Y - posMouseDown.Y);
                txb.Location = new Point(posStart.X + diff.X, posStart.Y + diff.Y);
            }
    
            private void txb_MouseUp(object sender, MouseEventArgs e)
            {
                var txb = (TextBox)sender;
                txb.MouseMove -= txb_MouseMove;
                txb.MouseUp -= txb_MouseUp;
                txb.Cursor = Cursors.Default;
            }
    
            private void txb_TextChanged(object sender, EventArgs e)
            {
                var txb = (TextBox)sender;
    
                SizeF size;
                using (var g = Graphics.FromHwnd(txb.Handle))
                {
                    size = g.MeasureString(txb.Text, txb.Font);
                }
                txb.Size = new Size((int)size.Width + 2, (int)size.Height + 2);
            }
            private void txb_LostFocus(object sender, EventArgs e)
            {
                var txb = (TextBox)sender;
                if (string.IsNullOrEmpty(txb.Text))
                {
                    txb.Parent.Controls.Remove(txb);
                }
                else
                {
                    txb.SelectionLength = 0;
                    txb.SelectionStart = 0;
                }
            }
    
            private void AddChart()
            {
                this.chart = new Chart();
                this.chart.Width = 100;
                this.chart.Height = 100;
    
                var chartArea1 = new ChartArea();
                chartArea1.Name = "ChartArea1";
    
                var series1 = new Series();
                DataPoint dataPoint1 = new DataPoint(0D, 0D);
                DataPoint dataPoint2 = new DataPoint(1D, 1D);
                DataPoint dataPoint3 = new DataPoint(2D, 5D);
                DataPoint dataPoint4 = new DataPoint(3D, 3D);
    
                this.chart.ChartAreas.Add(chartArea1);
    
                this.chart.Location = new System.Drawing.Point(33, 25);
                this.chart.Name = "chart";
                series1.ChartArea = chartArea1.Name; ;
                series1.Name = "Series1";
                series1.Points.Add(dataPoint1);
                series1.Points.Add(dataPoint2);
                series1.Points.Add(dataPoint3);
                series1.Points.Add(dataPoint4);
    
                this.chart.Series.Add(series1);
                this.chart.Size = new System.Drawing.Size(393, 340);
                this.chart.SuppressExceptions = true;
                this.chart.TabIndex = 0;
                this.chart.Text = "chart";
                this.chart.Visible = true;
    
                this.Controls.Add(chart);
            }
        }
    }
    #3.5のChartは使いづらいね


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2021年2月12日 11:11
  • Nishi0410さん、こんにちは。フォーラムオペレーターのHarukaです。
    MSDNフォーラムにご投稿くださいましてありがとうございます。

    チャートはどのように作成しましたか。
    System.Windows.Controls.DataVisualization.Toolkitを使用してグラフを描くのと似ていますか。 
    そうでない場合は、チャートの情報とコードスニペットを教えていただけますでしょうか。

    ちなみに、gekkaさんのデモでテストしましたか。
    それが機能しましたか。それとも何か質問がありますか。

    どうぞよろしくお願いいたします。

    MSDN/ TechNet Community Support Haruka
    ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、 ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~

    2021年2月18日 2:42
    モデレータ