PointToScreen problem in UserControl

A

A Nonymous

I created a PopUp edit based on a UserControl. It has a TextBox and a
button and works like a DateTimePicker except that in addition to date
and time, you can pick repeat intervals, days of the week, second
Tuesday, etc.

The problem is with the positioning of the PopUp. Basically the first
time I call PointToScreen I don't get the correct coordinates. The code
fragment I am using is shown below:

private void btnPick_Click(object sender, EventArgs e)
{
Point P = this.PointToScreen(Point.Empty);
if (P.Y + this.Height + editWhen.Height <=
SystemInformation.WorkingArea.Bottom)
P.Y += this.Height;
else
P.Y -= editWhen.Height;
editWhen.Location = P;
editWhen.Show();
}

What happens is the first time I click the drop down button the edit
window appears usually somewhere near the upper left corner of the
screen, but some times still on my app but near the upper corner of the
client area. The location is not completely consistent.

Now if I click the button again the dialog goes away, as designed, and
if I click it again it appears in the correct position. In fact from
then on I can just keep clicking on the button and it is always in the
correct location. I can even move the main form that contains my custom
edit and it is still correct.

It is only wrong, the first time I click the drop down button after the
form is created.

Any ideas on what is causing this, or how to fix it?
 
F

Fred Hebert

I don't know why you're converting to screen coordinates in the first
place, and I don't know why the code you posted should ever work, but
given that you are using screen coordinates, you need to convert back
to client coordinates for the containing control so that they are
correct when you assign the Location property.

Pete
editWhen is a form. Yes controls on a form use coordinates that are
relitave to the uuiper left of the parent form client area. Forms,
however, use screen relitave coordinates. PointToScreen Translates the
control cordinates on a form, say (10, 10) to screen coordinates like (273,
489).

To get a ComboBox or DateTime picker behaviour where a small frameless
window appears directly below the edit, I use the above code. I have used
thie technique before to position forms below edits. The difference was in
the past I would start with a new control based on say a TextBox, then
override the paint to draw the drop down button and a bunch of other things
to make it work. This time I tried the "easier" method that I got from the
MSDN site and started with a UserControl.

When the control is based on a UserControl it doesn't seem to work the
first time.
 
A

A Nonymous

Here are the simplest steps to reproduce:

1. Create a new windows forms project called "WhenPickerTest".

2. Add a UserControl called "clsWhenPicker" set the Size to 120,20.

3. To the user control add a TextBox and set the Location to 0,0, Size
to 100,20, Anchor to all 4 sides.

4. Next add a Button to the project and set its Location to 100,0, Size
to 20,20.

5. In the source of the UserControl just above the constructor add the
following line:
private Form Picker;

6. In the constructor after InitializeComponent add the following lines:
Picker = new Form();
Picker.BorderStyle = BorderStyle.None;
Picker.BackColor = Color.Green;
Picker.Size = new Size(200, 200);
Picker.Hide();

7. Go back to the designer and double click on the button. In the
Button1_Click add the following code:
If (Picker.Visible)
Picker.Hide();
else
{
Point P = this.PointToScreen(Point.Empty);
if (P.Y + this.Height + Picker.Height <=
SystemInformation.WorkingArea.Bottom)
P.Y += this.Height;
else
P.Y -= Picker.Height;
Picker.Location = P;
Picker.Show();
}

8. Compile, then go to the project main for designer. you should be
able to drop a clsWhenPicker on the form.

I think that will do it. If you compile and run you should get the form
with the clsWhenPicker. If you click the drop down button, the first
time the Picker form will probably be located somewhere near the upper
left corner of your screen. Click the button again to close the drop
down, then again to reopen. The second and subsequent times the Picker
form should be in the correct place which is immediately below the
TextBox.

Now this is missing a lot of code but I wanted to keep it simple. In
the actual control I created the "Picker" form is much more complex. I
hide the form when it looses focus and subclass the main form so the
title bar does not lose focus when the Picker is visible, and other
niceties, but this is good enough to demonstrate the problem.
 
A

A Nonymous

Peter,

Your responses seem terse and condescending. If you don't want to help and
you see everyone that is asking a question as dumber than you, then why do
you bother.

I thought my initial question was sufficient in that I wanted to know if
anyone was aware of any quirks when using PoiintToScreen in a UserControl.

If you don't know, don't answer.

I don't want to upload a zipped project to the newsgroup, and because of
the type of problem you can't express it in a single file.

Apart from a few clicks I included all of the source needed to recreate a
project to demonstrate the problem. I thought I was doing you a favor
because you might learn something, when someone else answered the problem.

I think my impression of you based on your first response was accurate.
You are completely unfamiliar with this problem and this technique. Have
you ever created a control with DateTimePicker or ComboBox like drop down
behavior? (It's a rhetorical question...)

Please don't bother trying to help with this problem, I have already
decided that it is easer to do it the way I have always done it. There is
definitely something different about using the UserControl.

Thanks for the effort.
 
A

A Nonymous

Pete,

Here again, you obviously misunderstood me.

I don't want you to check my code. I just want to know if anyone else
has seen this problem and knows how to fix it.

And by the way I spent some time with Google and discovered the source
of the problem. It is not actually the PointToScreen at all, but the
StartPosition setting of the form being popped up. If it is not set to
Manual, the first time the form is shown any location that was set is
overridden. Normally when I create a create components like this I hard
code everything. Using a UserControl and dropping components on it is
easier but it is also easy to miss something.

This was the first time I used this technique, and I am relatively new
to C# (but not new to programming). It was a dumb mistake but I have
learned.

So less time? Well I wasn't asking anyone to check my code and if you
knew the answer you could just answer as above. (Did you check the
Form.StartPosition?)

I apologize if everything is not what you expected or exactly the way
you would like it to be.

So relax, Please.

Sorry I can't resist, my hostility and selfishness makes me do it, and I
just like poking at pompous people.

Actually I didn't think I was hostile by pointing out that you seemed
terse and condescending. And as far as selfish, how is asking for help
selfish? I do give back, and post solutions when I find them even if
the solution was not provided here. I do help others, albeit
anonymously.

Even though I have been programming for many years I don't assume I am
superior to anyone. I listen to everyone even novices because anyone can
have a good idea, and even the smartest person can't know everything.

I know you probably think you know more than anyone here. I think you
are probably under 30, been programming for a few years and are fairly
sharp, but not necessarily the smartest one here. I am glad that you
try to help, but now that I have looked at some of your other posts to
other people, I see a pattern. Get over yourself.

I bet you blood pressure is shooting up as you read this...

Have a nice day. ;-)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top