none
Клавиши влево-вправо-вверх-вниз на графике не вызывают событие Chart_KeyDown RRS feed

  • Вопрос

  • Всем привет!
    Проблема.
    DataVisualization.Charting;
    График не чувствует нажатие клавиш со стрелками - влево, вправо, вверх, вниз.
    С клавишей Control эти клавиши работают, а без нее даже событие не возникает,
    а хотелось бы, чтобы возникало...
    Все остальные клавиши работают, а эти нет.
    К чему бы это?

    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Drawing;
    using System.Windows.Forms;
    using System.Windows.Forms.DataVisualization.Charting;
    
    public	partial	class	MainForm  : Form
    {	public	MainForm()
    	{	InitializeComponent();
    		SimpleChart C = new SimpleChart	( ... );
    		C.Show ();
    		C.Activate ();
    	}
    	KeyDown += new KeyEventHandler( MainForm_KeyDown );
    	private void MainForm_KeyDown (	object o, KeyEventArgs e )
    	{
    		if ( e.KeyCode == Keys.Escape ) Close ();
    }	}
    
    public class	SimpleChart	:	Form
    {	public		SimpleChart	( ... )		{	InitializeComponent ();	}
    	private		Chart	chart;
    	Series		serie;
    	ChartArea	chartArea;
    	private		void	InitializeComponent	()
    	{	chartArea	=	new ChartArea();
    		serie		=	new Series();
    		chart		=	new Chart();
    		SuspendLayout();
    		((System.ComponentModel.ISupportInitialize)	(	chart )	).BeginInit();
    		
    		//	
    		// chart
    		// 
    		...
    		...
    		...
    		
    		Controls.Add(	chart	);
    		Location	=	new Point	( ... );
    		Size		=	new Size	( ... );
    		Text		=	"Text";
    		((System.ComponentModel.ISupportInitialize)	(	chart )	).EndInit();
    		StartPosition =	FormStartPosition.Manual;
    		...
    		...
    		...
    		chart.KeyDown	+=	new KeyEventHandler ( SimpleChart_KeyDown );
    	}
    // ??? При нажатии стрелок без Control это событие не возникает ???	
    	private	void	SimpleChart_KeyDown	( object o, KeyEventArgs e )
    	{	if ( e.KeyCode == Keys.Escape ) Close ();
    		if ( e.Control && e.KeyCode == Keys.Down ) {}
    		if ( e.Control && e.KeyCode == Keys.Left ) {}
    		if ( e.Control && e.KeyCode == Keys.Right) {}
    		if ( e.Control && e.KeyCode == Keys.Up	 ) {}
    	}				
    }
    


    • Изменено QazRdx 8 октября 2019 г. 14:23
    8 октября 2019 г. 14:20

Ответы

  • Клавиши-стрелки зарезервированы в Windows Forms для особых целей: перемещения фокуса между кнопками, перемещения курсора в TextBox. На уровне пользовательских обработчиков они просто не обрабатываются.

    Можно использовать PreviewKeyDown, он обрабатывает и эти клавиши:

            private void chart1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
            {
                if (e.KeyCode == Keys.Up) { /*...*/ }
            }

    Однако, в вашем коде есть еще одна проблема: вы пытаетесь обработать нажатия клавиш в элементе Chart, который не переключает на себя фокус при нажатии клавиш. Другие элементы - например кнопки, напротив, переключают. Если у вас на форме будет еще какие-то элементы, есть хороший шанс, что все будет работать не так, как вы ожидаете; ведь индивидуальные обработчики элементов вызываются только когда элемент в фокусе. Более правильным, мне кажется, было бы обрабатывать на уровне формы:

            protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
            {            
                if (keyData == Keys.Up)
                {
                    //...
                    return true;
                }
                
                return base.ProcessCmdKey(ref msg, keyData);
            }
    Но недостаток этого способа - перемещение курсора стрелками в TextBox работать не будет...

     

    11 октября 2019 г. 4:50

Все ответы

  • Клавиши-стрелки зарезервированы в Windows Forms для особых целей: перемещения фокуса между кнопками, перемещения курсора в TextBox. На уровне пользовательских обработчиков они просто не обрабатываются.

    Можно использовать PreviewKeyDown, он обрабатывает и эти клавиши:

            private void chart1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
            {
                if (e.KeyCode == Keys.Up) { /*...*/ }
            }

    Однако, в вашем коде есть еще одна проблема: вы пытаетесь обработать нажатия клавиш в элементе Chart, который не переключает на себя фокус при нажатии клавиш. Другие элементы - например кнопки, напротив, переключают. Если у вас на форме будет еще какие-то элементы, есть хороший шанс, что все будет работать не так, как вы ожидаете; ведь индивидуальные обработчики элементов вызываются только когда элемент в фокусе. Более правильным, мне кажется, было бы обрабатывать на уровне формы:

            protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
            {            
                if (keyData == Keys.Up)
                {
                    //...
                    return true;
                }
                
                return base.ProcessCmdKey(ref msg, keyData);
            }
    Но недостаток этого способа - перемещение курсора стрелками в TextBox работать не будет...

     

    11 октября 2019 г. 4:50
  • Спасибо!
    PreviewKeyDown - решение проблемы,
    chart чувствует ВСЮ клавиатуру,
    включая комбинации клавиш с Ctrl, Shift и Alt.
    Что касается второго замечания, непереключение фокуса на chart, -
    у меня chart фокусируется при построении,
    и после нажатия на любую
    клавишу фокус не меняется,
    что меня абсолютно устраивает.
    Еще раз спасибо!
    12 октября 2019 г. 6:00