return focus to a Windows.Forms.DataGridView

how do I keep the editing of the selected cell the same?

Page 1 of 1

11 Replies - 5226 Views - Last Post: 10 November 2010 - 09:24 AM Rate Topic: -----

#1 lordofduct  Icon User is offline

  • I'm a cheeseburger
  • member icon


Reputation: 2528
  • View blog
  • Posts: 4,630
  • Joined: 24-September 10

return focus to a Windows.Forms.DataGridView

Posted 02 November 2010 - 08:08 AM

Upfront: please excuse the length of the post, there's a bit of information I have to lay down to explain my situation. So bare with me please.



So I checked the .Net framework forum, and there was no 'general' section, nor was there a 'Windows.Forms' section (but there was a WPF section...). I attempted posting a similar question to this post in the VB.Net forum, with no assistance. The only reason is because the job is in VB. But really the question I have is not really VB dependent and is a .Net issue. Because I prefer C# over VB, and most of the skilled .Net users I've seen around the forum seem to also prefer C#, I'm going to post this here.


My Question:

So I have a simple on screen keyboard control. It's just a custom Control with a bunch of buttons laid out like a Numpad. When it's clicked I use SendKeys to simulate a key press of that number. Of course when the user presses each button, the focus is given to the button being clicked and I need to manually return it back to the control that had the focus prior. I do this by listening to the leave event of all controls I considered 'managed' and remember the last one that had focus, and return said focus.

Rather simple.

When returning focus these controls generally remember the state of their selection if they were (if a TextBox it remembers what, if any, text was highlighted by the user. And where the input carriage belongs).

But one stupid Control type gives me a giant pain in the arse.

DataGridView

The DataGridView as I've come to learn (keep in mind I come from other languages, then to mono, and now to actual .Net and only recently started playing with the Windows.Forms namespace... I hate it, sorry), it uses a smart little method of reducing memory required by the Control. When you go to edit any cell an 'EditingControl' is created for the cell temporarily, then once the cell is left and validated, that 'EditingControl' is disposed of in some manner. Smart in some respects, but deals one majour blow to my system.

When leaving the DataGridView that is being edited mode to strike this button and returning back to the DataGridView, the EditingControl had been disposed of and doesn't remember its state. Calling 'Focus' brings it back into focus, and the cell is in edit more (because the DataGridView remembers), but the cell itself is in a default selected mode (for a text cell the text is all highlighted, not good if we want subsequent key strikes).

With some hacking a work mate of mine found different ways to deal with it. All of them hacky, and none of them really working out exactly how we hope.

The best one he found was when leaving a Control we check if it is a DataGridView, set the forms active control to the 'EditingControl' (yeah, that's the super hacky part I hate, but it keeps it from getting disposed), then when the button for the numpad is clicked we check if the last control was a DataGridView or not, if not we call Focus, if is we call BeginEdit.

But as one would suspect this hack causes the 'EditingControl' to get stuck on screen, as I expected something of the likes to occur.




So I ask of you guys, do you have any experience with this one hell of an annoying Control, this problem, and have any ideas how to deal with it?


The specific functionality we expect is that when we return focus to the last active control before hitting the numpad, that the selected/highlighted state of the control is how it was when we left. All controls accept for DataGridView act as expected... but editable DataGridViews play a huge role in the project.

This post has been edited by lordofduct: 02 November 2010 - 08:12 AM


Is This A Good Question/Topic? 0
  • +

Replies To: return focus to a Windows.Forms.DataGridView

#2 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5436
  • View blog
  • Posts: 11,649
  • Joined: 02-June 10

Re: return focus to a Windows.Forms.DataGridView

Posted 02 November 2010 - 09:52 AM

We have a lovely tutorial for a keyboard here that should help a lot

Bulding an application - Part 1
Building an application - Part 2
Was This Post Helpful? 0
  • +
  • -

#3 eclipsed4utoo  Icon User is offline

  • Not Your Ordinary Programmer
  • member icon

Reputation: 1524
  • View blog
  • Posts: 5,957
  • Joined: 21-March 08

Re: return focus to a Windows.Forms.DataGridView

Posted 02 November 2010 - 10:14 AM

View PosttlhIn, on 02 November 2010 - 12:52 PM, said:

We have a lovely tutorial for a keyboard here that should help a lot

Bulding an application - Part 1
Building an application - Part 2


Did you even read the post?
Was This Post Helpful? 0
  • +
  • -

#4 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5436
  • View blog
  • Posts: 11,649
  • Joined: 02-June 10

Re: return focus to a Windows.Forms.DataGridView

Posted 02 November 2010 - 10:32 AM

View Posteclipsed4utoo, on 02 November 2010 - 09:14 AM, said:

View PosttlhIn, on 02 November 2010 - 12:52 PM, said:

We have a lovely tutorial for a keyboard here that should help a lot

Bulding an application - Part 1
Building an application - Part 2


Did you even read the post?


As a matter of fact I did.

Quote

My Question:

So I have a simple on screen keyboard control. It's just a custom Control with a bunch of buttons laid out like a Numpad. When it's clicked I use SendKeys to simulate a key press of that number. Of course when the user presses each button, the focus is given to the button being clicked and I need to manually return it back to the control that had the focus prior. I do this by listening to the leave event of all controls I considered 'managed' and remember the last one that had focus, and return said focu


The tutorial shows how to build a keypad that doesn't take focus away from the calling control - thus eliminating the entire problem the user is trying to bandaid. Rather than fix the problem after it happens by returning focus, wouldn't it be better to just never loose the focus?

Quote

I do this by listening to the leave event of all controls I considered 'managed' and remember the last one that had focus
Sounds like monkey humping a football. Why go through all that when you don't have to?

Quote

With some hacking a work mate of mine found different ways to deal with it. All of them hacky, and none of them really working out exactly how we hope.


I thought I'd offer an alternative and possibly better way to build the keypad which is the heart of the problem.

I have this weird and silly way of coding where I prefer to eliminate the problem rather than code a hack/fix/patch/cludge afterward.

Rather than snidely jumping me with "did you even read the question" perhaps you would like to offer something constructive, like a suggestion to the OP on how to fix the their problem. Its easy to be a coach from the bleachers. How about jumping into the game?
Was This Post Helpful? 1
  • +
  • -

#5 lordofduct  Icon User is offline

  • I'm a cheeseburger
  • member icon


Reputation: 2528
  • View blog
  • Posts: 4,630
  • Joined: 24-September 10

Re: return focus to a Windows.Forms.DataGridView

Posted 02 November 2010 - 11:00 AM

Yes actually it would be better to never lose the focus. I hadn't been able to find a way to do that either.

And I completely agree, I hate solving the problem in a hackish manner (to tell you the truth I hate remember the last control focused as well. It just feels so retarded, but alas I'm not the one with control over this project... and ummm... yeah, not going to get into that one).


Anyways though, unless I missed it... I don't see in the thread how you are stopping the buttons from stealing focus. I see some stuff about raising a custom event (which I actually do), but that still doesn't stop the button from taking focus. I also notice in the articles you posted that the code is merely appending to the end of the 'Text' property... which in turn would require me to know what the last control was (this needs to react how a normal keyboard input reacts for any given Control), and it doesn't necessarily always append... it needs to retract text that may have been selected by the user (this is why I cooped SendKeys which acts like a real key press).

This post has been edited by lordofduct: 02 November 2010 - 11:06 AM

Was This Post Helpful? 0
  • +
  • -

#6 eclipsed4utoo  Icon User is offline

  • Not Your Ordinary Programmer
  • member icon

Reputation: 1524
  • View blog
  • Posts: 5,957
  • Joined: 21-March 08

Re: return focus to a Windows.Forms.DataGridView

Posted 02 November 2010 - 01:08 PM

View PosttlhIn, on 02 November 2010 - 01:32 PM, said:

The tutorial shows how to build a keypad that doesn't take focus away from the calling control - thus eliminating the entire problem the user is trying to bandaid. Rather than fix the problem after it happens by returning focus, wouldn't it be better to just never loose the focus?


So in your "Part One" tutorial, at the bottom, where you add it to a form that has a Textbox. If you click in the textbox, type a "1", then click the button for "0", is your cursor still in the TextBox? or is it now the Button that has focus?

Going by this screenshot in your tutorial, the button now has focus and not the textbox.
Was This Post Helpful? 0
  • +
  • -

#7 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5436
  • View blog
  • Posts: 11,649
  • Joined: 02-June 10

Re: return focus to a Windows.Forms.DataGridView

Posted 02 November 2010 - 01:43 PM

View Posteclipsed4utoo, on 02 November 2010 - 12:08 PM, said:

View PosttlhIn, on 02 November 2010 - 01:32 PM, said:

The tutorial shows how to build a keypad that doesn't take focus away from the calling control - thus eliminating the entire problem the user is trying to bandaid. Rather than fix the problem after it happens by returning focus, wouldn't it be better to just never loose the focus?


So in your "Part One" tutorial, at the bottom, where you add it to a form that has a Textbox. If you click in the textbox, type a "1", then click the button for "0", is your cursor still in the TextBox? or is it now the Button that has focus?

Going by this screenshot in your tutorial, the button now has focus and not the textbox.


I have overhauled my keypad code/object/pallet many times since writing that tutorial. It is altogether possible that my head is filled with the *current* incarnation and not the tutorial version.

Let me go back over it before shoving my foot even deeper in my mouth. I may even need to update it this weekend.
Was This Post Helpful? 0
  • +
  • -

#8 lordofduct  Icon User is offline

  • I'm a cheeseburger
  • member icon


Reputation: 2528
  • View blog
  • Posts: 4,630
  • Joined: 24-September 10

Re: return focus to a Windows.Forms.DataGridView

Posted 02 November 2010 - 02:12 PM

thanks man, looking forward to it!
Was This Post Helpful? 0
  • +
  • -

#9 elbielefeld  Icon User is offline

  • D.I.C Head

Reputation: 70
  • View blog
  • Posts: 216
  • Joined: 18-May 10

Re: return focus to a Windows.Forms.DataGridView

Posted 02 November 2010 - 02:59 PM

Heres some code that may help:

using System;
using System.Windows.Forms;

namespace test
{
    public partial class Form1 : Form //Contains DataGridView
    {        
        public Form1()
        {
            InitializeComponent();
        }               

        private void button1_Click(object sender, EventArgs e)
        {
            Form2 f = new Form2(this);
            f.Show();
        }
    }
}




using System;
using System.Windows.Forms;

namespace test
{
    public partial class Form2 : Form
    {
        public const int WM_MOUSEACTIVATE = 33;
        public const int MA_NOACTIVATE = 3;
        public const int WM_NCMOUSEMOVE = 160;

        private Form _ParentForm;

        public Form2(Form parentForm)
        {
            InitializeComponent();
            this._ParentForm = parentForm;
        }

        protected override bool ShowWithoutActivation
        {
            get
            {
                return true;
            }
        }

        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case WM_MOUSEACTIVATE:
                {
                    m.Result = new IntPtr(MA_NOACTIVATE);
                    return;
                }
                case WM_NCMOUSEMOVE:
                {
                    if (!this.Capture)
                    {
                        this._ParentForm.Focus();
                    }
                    break;
                }
            }
            base.WndProc(ref m);
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {
            SendKeys.Send("0");
        }
    }
}



Note you cannot use controls that can obtain focus in the "on screen keyboard" (like buttons). You can use PictureBoxes instead. Seems to work fine so far with TextBoxe and DataGridView in the main form.
You can even move the keyboard window around and the focus is set back to the parent form afterwards.
Was This Post Helpful? 0
  • +
  • -

#10 lordofduct  Icon User is offline

  • I'm a cheeseburger
  • member icon


Reputation: 2528
  • View blog
  • Posts: 4,630
  • Joined: 24-September 10

Re: return focus to a Windows.Forms.DataGridView

Posted 08 November 2010 - 09:20 AM

@elbielefeld - this isn't an issue about returning to another form (it's actually in the same form). And I'm kind of restricted to a specific button control (I should have said that before as well, I don't have control over the graphical design).


@tlhIn'toq - any luck on the newer version?

Though it's not urgent, I'm personally working on other things, so not even I have had a chance to play with this more (hence why I haven't commented in this thread since last Tuesday).

This post has been edited by lordofduct: 08 November 2010 - 09:21 AM

Was This Post Helpful? 0
  • +
  • -

#11 elbielefeld  Icon User is offline

  • D.I.C Head

Reputation: 70
  • View blog
  • Posts: 216
  • Joined: 18-May 10

Re: return focus to a Windows.Forms.DataGridView

Posted 08 November 2010 - 11:58 AM

Depending on this custom control, this may help:

    public partial class Form1 : Form
    {
        public const int WM_MOUSEACTIVATE = 33;
        public const int MA_NOACTIVATE = 3;
        public const int WM_PARENTNOTIFY = 528;
        public const int WM_LBUTTONDOWN = 513;

        private bool _NoActivate;

        public Form1()
        {
            InitializeComponent();
        }

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_MOUSEACTIVATE && _NoActivate)
            {
                m.Result = (IntPtr)MA_NOACTIVATE;
                _NoActivate = false;
                return;
            }

            if (m.Msg == WM_PARENTNOTIFY)
            {
                if (m.WParam == (IntPtr)WM_LBUTTONDOWN)
                {
                   Control child = this.GetChildAtPoint(new System.Drawing.Point(m.LParam.ToInt32() & 0xFF, m.LParam.ToInt32() >> 16));
                   if (child == yourControl) _NoActivate = true;
                }
            }
            base.WndProc(ref m);
        }
    }



But if the custom control takes the focus on a WM_LBUTTONDOWN message (like most windows forms controls do) this will not work and I think there is no other way.
Was This Post Helpful? 0
  • +
  • -

#12 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5436
  • View blog
  • Posts: 11,649
  • Joined: 02-June 10

Re: return focus to a Windows.Forms.DataGridView

Posted 10 November 2010 - 09:24 AM

Quote

@tlhIn'toq - any luck on the newer version?

Though it's not urgent, I'm personally working on other things, so not even I have had a chance to play with this more (hence why I haven't commented in this thread since last Tuesday).


I thought I was going to have this current week to myself. I was wrong. My boss called me on Sunday needing help getting his part of a new project done in time for the sneak-peek unveiling this weekend at a tradeshow. I've had my boss in my house every day since Sunday so we can work on his application. There is been no opportunity to do anything else.

On the other hand, I'm taking all of December off from work. I'm hoping to spend some quality time on creating tutorials.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1