7 Replies - 509 Views - Last Post: 21 January 2013 - 05:43 PM Rate Topic: -----

#1 CrimsonPhoenix  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 27-July 12

Inconsistent Docking using WinForms

Posted 17 January 2013 - 09:04 PM

Hi All,

I have UserControls for the sections below the main menu which all have Dock set to Fill. This works absolutely fine and they were dragged onto the GUI using Visual C# Express. However, when I programatically try and add one, it docks it but also places it behind the menu (as seen in the screenshot). How can I prevent this?

http://i48.tinypic.com/2vn54ev.jpg

Image 1) The ProjectView UserControl docked incorrectly. This is the problematic part, it was added programattically (using the code here: {removed}). However it seems to be placing the control behind the menu rather than directly below it (like the PeopleView control that was added using the GUI)

Image 2) The "PeopleView" UserControl docked correctly onto the main form. This was done using the GUI by dragging an instance of PeopleView onto the display and then setting Dock to DockStyle.Fill

Image 3) the "PeopleView" UserControl on its own

Image 4) the "ProjectView" Usercontrol on its own

The code to add is identical to the designer, apart from the fact that it is this.Parent.Controls.Add rather than this.Controls.Add because the control I am trying to add is inside another UserControl.

Any ideas?

Thanks =)

This post has been edited by tlhIn`toq: 18 January 2013 - 07:47 AM
Reason for edit:: Please place code directly in the post


Is This A Good Question/Topic? 0
  • +

Replies To: Inconsistent Docking using WinForms

#2 tlhIn`toq  Icon User is offline

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

Reputation: 5535
  • View blog
  • Posts: 11,857
  • Joined: 02-June 10

Re: Inconsistent Docking using WinForms

Posted 18 January 2013 - 07:46 AM

First - If you have the option to go to WPF and leave WinForms behind, do it.

Quote

However, when I programatically try and add one, it docks it but also places it behind the menu (as seen in the screenshot). How can I prevent this?


Changing the Z order of controls isn't well supported. Basically you have to add them in the reverse order as if building them from the bottom to the top.

Since that is a pain in the ass, I recommend better layout of the form. Put in panels that are never removed to create your overall design. Then swap the contents of the middle "workspace" panel. The advantage here is you can set the scroll controls of the panel to auto. Then if your usercontrol is bigger than the form the user can still scroll around it.
Was This Post Helpful? 1
  • +
  • -

#3 CrimsonPhoenix  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 27-July 12

Re: Inconsistent Docking using WinForms

Posted 18 January 2013 - 08:46 PM

View PosttlhIn`toq, on 19 January 2013 - 12:46 AM, said:

Since that is a pain in the ass, I recommend better layout of the form. Put in panels that are never removed to create your overall design. Then swap the contents of the middle "workspace" panel. The advantage here is you can set the scroll controls of the panel to auto. Then if your usercontrol is bigger than the form the user can still scroll around it.


Thanks for the reply! When I programatically added the UserControl (the one that is not displaying correctly) to the display it was from another UserControl (called ProjectPanel) and not the main form. I really like your idea to add a 'workspace' panel, but since that workspace panel would reside on the main form it would be unable to be accessed from the ProjectPanel UserControl class. Making the workspace panel public and passing a reference to the main form to the ProjectPanel class would work but that seems extremely dirty and there must be a better way to do it.

Open to suggestions and really appreciate your input so far!
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: 5535
  • View blog
  • Posts: 11,857
  • Joined: 02-June 10

Re: Inconsistent Docking using WinForms

Posted 19 January 2013 - 07:48 AM

View PostCrimsonPhoenix, on 18 January 2013 - 09:46 PM, said:

I really like your idea to add a 'workspace' panel, but since that workspace panel would reside on the main form it would be unable to be accessed from the ProjectPanel UserControl class.


It's SUPPOSED to be inaccessable to other classes. You're not supposed to be making your GUI elements public and directly accessing them from other classes. That's BAD/frowned upon/not done in the work world - so don't start those bad habits now and you won't have to break them later.

You are supposed to keep these classes unaware and not tightly bound to each other. They should be little black boxes of code that know nothing or very little of each other. These tutorials from my FAQ should help. Stop working on this project for an hour, do the tutorials, then go back to the whiteboard with your knew and improved understanding, with better whiteners and brighteners.

Q: ...get Form 'A' to make a change or talk to Form 'B'

NOTE: Don't try to access GUI controls across forms. Its wrong. Nobody will hire you if you do this sort of crap. It violates every guideline for 'black box' programming, Separation of Responsibility, loose binding of components, and event driven programming. Read the tutorials and learn to do it right the first time so you don't develop bad habits that you just have to un-learn later.
A:
Was This Post Helpful? 2
  • +
  • -

#5 CrimsonPhoenix  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 27-July 12

Re: Inconsistent Docking using WinForms

Posted 20 January 2013 - 07:04 PM

Hi,

Thanks very much for your replies.

The following screenshot will help in understanding the situation: http://i45.tinypic.com/sgpnnr.png

So this means the best way to go about it is using events. However, would this mean that I need to create an event in each UserControl that I want the main form to listen to in order to be able to add it to the workspace panel?

The only issue I can see with this is the fact that the main form is completely unaware of some of these UserControls. For example: I have a ProjectPanel which I added to the workspace panel via the GUI, which works fine. The issue is the fact that there is another UserControl named ProjectView which is instantiated from within the ProjectPanel class when the user clicks a "Manage Project" button. The main form is completely unaware of the ProjectView class, so how could the main form subscribe to an event in the ProjectView class telling it to add it to the workspace panel?
Was This Post Helpful? 0
  • +
  • -

#6 tlhIn`toq  Icon User is offline

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

Reputation: 5535
  • View blog
  • Posts: 11,857
  • Joined: 02-June 10

Re: Inconsistent Docking using WinForms

Posted 20 January 2013 - 07:15 PM

You're still missing an understanding of the event raise and subscribe relationship.

The form doesn't need to subscribe to an event just to add the control. And the control doesn't have to raise an event in order to allow the form to add it.

You only need events to communicate between the two classes. And if that's going to happen, they I would expect the form needs to know at least something of the control so it knows what to do when the event is raised.

How about this.... Picture a bingo parlor.
The guy calling the numbers doesn't need to know much about the players. These are your two classes: NumberCaller and Player.
The NumberCaller doesn't know any of the players by name or maybe even know how many there are. He has one job: To raise the event
NewNumber(NumberArguments). The players subscribe to that event (they listen for the numbers to be called). When they yell out "Bingo" (they raise their own 'Bingo' event) - then another class (the CardVerifier) does his thing to validate the card.

The analogy continue in that the caller doesn't require any events or subscriptions from the players. As many as they like can join the game.


If you need some kind of interaction between the classes, then yes you need to know the events so you can subscribe to them. But if the UserControl doesn't have to talk to the main form because everything. it does is self contained, then just drop the UserControl on the form. No muss no fuss.
Was This Post Helpful? 2
  • +
  • -

#7 CrimsonPhoenix  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 27-July 12

Re: Inconsistent Docking using WinForms

Posted 21 January 2013 - 03:52 PM

Hi,

Thanks for your continued assistance.

I have to pass a value to the ProjectView UserControl instance (a project ID, so the control knows which database record to retrieve data from), which from your previous emails, leads me to believe that the best way to go about it is to define a custom event.

Just to recap the function of each control:
- ProjectPanel: Contains a list of projects
- ProjectView: Contains the details for a selected project
- Main Form: The place where everything is displayed, in a panel referred to as the "workspace panel"

A custom event is fired when the user clicks the [Manage Project] button (located on the ProjectPanel UserControl). The Main Form listens to this event and then displays the ProjectView user control (using the specified ID) in the workspace panel.

public class UserObjectEventArgs : EventArgs
{
    public object UserObject;

    public UserObjectEventArgs(object userObject)
    {
        this.UserObject = userObject;
    }
}



In ProjectPanel:
public event EventHandler<UserObjectEventArgs> ProjectViewLaunched;


and in the Event Handler for the [Manage Project] button:
        private void manageProjectButton_Click(object sender, EventArgs e)
        {
            if (projectsListBox.SelectedIndex == -1)
            {
                KryptonMessageBox.Show("You must select a project to manage.", "Select a Project");
                return;
            }

            string projectID = ((Project)((MyListBoxItem)projectsListBox.SelectedItem).UserObject).ID;
            if(string.IsNullOrWhiteSpace(projectID))
            {
                KryptonMessageBox.Show("Cannot load project - unable to find a project ID for this project", "Unable To Load Project");
                return;
            }

            if (ProjectViewLaunched != null)
            {
                ProjectViewLaunched(this, new UserObjectEventArgs(projectID));
            }
        }



It works perfectly, but just wanted to confirm if this is an acceptable way to do this?

Really appreciate all your help so far, I have hit 'Helpful' on your posts, does this forum also have a Reputation system?
Was This Post Helpful? 0
  • +
  • -

#8 tlhIn`toq  Icon User is offline

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

Reputation: 5535
  • View blog
  • Posts: 11,857
  • Joined: 02-June 10

Re: Inconsistent Docking using WinForms

Posted 21 January 2013 - 05:43 PM

I don't think I like the idea of both a listbox and a button.
ONe should be able to just change the selection of the listbox and have the selected project get loaded. No need for the added step of sliding off the listbox to the button then click.

I think I'd personally do something more like this:
void lbProjects_SelectedIndexChanged(object sender, EventArgs e)
{
   ProjectViewUC.ProjectID = lbProjects.SelectedItem;
   // When the ProjectViewUC.ProjectID is set, the view then loads the details of the project from the database or from serialized XML or whatever.  But the responsibility for this lies with the UserControl not the main application.
}

This post has been edited by tlhIn`toq: 21 January 2013 - 05:43 PM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1