Results 1 to 12 of 12

Thread: [RESOLVED] Container line

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Dec 2011
    Location
    Oregon City, Oregon
    Posts
    703

    Resolved [RESOLVED] Container line

    I like to group controls on a form using containers. Typically I use a panel, but sometimes use a combobox. I like to have a fixed line around the container, but I would like to define the color that line should be. I have found nothing in the properties that would allow me to do this. Is there a property that can be defined to set the color of the line, if a fixed line is used?

  2. #2
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,943

    Re: Container line

    I don't know of one for the only 'fixed line' control that I am aware of, which is the GroupBox.

    However, I often like to divide up controls into groups, as well, and when I want a line, black or some other color, I use a label. This only works for vertical or horizontal lines. If you want any other kind of line, you could use a GraphicsPath object, but that will take more effort. To use a label, you set the backcolor to whatever color you want, set AutoSize to False, then set either the height (horizontal) or width (vertical) to 1, 2, or whatever thickness you want.

    The other option would be to draw a rectangle, but that would have to be done in the Paint event handler for it to work right.
    My usual boring signature: Nothing

  3. #3

    Thread Starter
    Fanatic Member
    Join Date
    Dec 2011
    Location
    Oregon City, Oregon
    Posts
    703

    Re: Container line

    That's cool about using a label. I never would have thought of that. Sometimes you have to think out of the box (pun intended).

  4. #4
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,943

    Re: Container line

    I didn't come up with it. Back in VB6, there was a Line control. You can still find something like that in the VB PowerPacks supplement, but the supplement is otherwise a pain in the butt, and using the Line control from that is in no way superior to the GraphicsPath, other than the fact that it raises click events (which you can simulate using the GraphicsPath). Since .NET didn't have the Line Control, I went online (possibly here) looking for an alternative.

    However, I started into .NET with the old CE, which stood for Compact Edition at the time (it's now used for Community Edition). The CE version worked on mobile devices, which meant PDA devices. The CE version also lacked lots of controls like ListBoxes, so writing for that version meant finding ways to use existing controls to compose what you wanted. For example, a Listbox was a panel with a bunch of labels on it and a vertical scroll bar. As you moved the scrollbar, you changed which item was in each label. These days, there are better controls that do that, such as the FlowLayoutPanel and User Controls, but those didn't exist for the CE version. Doing odd things with labels was just one of the tricks.
    My usual boring signature: Nothing

  5. #5
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,274

    Re: Container line

    Quote Originally Posted by gwboolean View Post
    I like to group controls on a form using containers. Typically I use a panel, but sometimes use a combobox.
    That doesn't seem to make sense. Did you mean a GroupBox?

    It's easy enough to create a border yourself. Here's a control derived from Panel that has a one-pixel border of whatever colour you like:
    vb.net Code:
    1. Imports System.ComponentModel
    2.  
    3. Public Class BorderedPanel
    4.     Inherits Panel
    5.  
    6.     Private _borderColor As Color = Color.Black
    7.  
    8.     <Category("Appearance")>
    9.     <Description("The colour of the border")>
    10.     Public Property BorderColor As Color
    11.         Get
    12.             Return _borderColor
    13.         End Get
    14.         Set(value As Color)
    15.             If _borderColor <> value Then
    16.                 _borderColor = value
    17.                 OnBorderColorChanged(EventArgs.Empty)
    18.             End If
    19.         End Set
    20.     End Property
    21.  
    22.     Public Event BorderColorChanged As EventHandler
    23.  
    24.     Protected Overridable Sub OnBorderColorChanged(e As EventArgs)
    25.         'Repaint the control to update the colour of the border.
    26.         Refresh()
    27.  
    28.         RaiseEvent BorderColorChanged(Me, e)
    29.     End Sub
    30.  
    31.     Protected Overrides Sub OnPaint(e As PaintEventArgs)
    32.         MyBase.OnPaint(e)
    33.  
    34.         Using p As New Pen(BorderColor)
    35.             e.Graphics.DrawRectangle(p, 0, 0, Width - 1, Height - 1)
    36.         End Using
    37.     End Sub
    38.  
    39. End Class
    If you add that class to your project and build then you can add an instance from the Toolbox just like any other control. You can also build it into a DLL and add it to the Toolbox for every project.

    Obviously that won't have the nice rounded corners that a GroupBox has but you can modify the code in the OnPaint method to draw whatever you like.

  6. #6

    Thread Starter
    Fanatic Member
    Join Date
    Dec 2011
    Location
    Oregon City, Oregon
    Posts
    703

    Re: Container line

    Shaggy, based on your historical comments you might even be older than me. That is so sad. But whatever the case, that is an approach I am going to keep in mind.

    JM, Yep, I did indeed mean a groupbox. I type so fast that my thoughts usually cannot keep up.

    What you provided is pretty cool. However, I am pretty ignorant about the use of classes like this. I guess it is time I learned what the hell is going on and how to do it. So let me see if I understand part of it, at least.

    OK, I have created the class, but I have never added a class to a project and build. I have added powerpacks and a few things like that. I would assume it is the same process, but I wouldn't even know where to look for it to add.

  7. #7

    Thread Starter
    Fanatic Member
    Join Date
    Dec 2011
    Location
    Oregon City, Oregon
    Posts
    703

    Re: Container line

    I am now able to see the Border Panel class in the toolbox and have added it to the form. In the properties I can see the properties I am after. This is the first time I have done something like this and while it might not be that big a deal for you guys, for me this is very, very cool.

    It took me awhile to figure it all out (that is assuming I actually have figured it all out), but I am setting it up and will be checking it out pretty soon. Thanks JM, you nailed by butt to the wall on this one.

  8. #8

    Thread Starter
    Fanatic Member
    Join Date
    Dec 2011
    Location
    Oregon City, Oregon
    Posts
    703

    Re: Container line

    Damn, it almost worked!!!! Actually, it does work, but for only the Top and the Left side. The Right side and the bottom do not show the line. So here is what I get in my first attempt using the panel:

    Name:  Panel.jpg
Views: 321
Size:  163.2 KB

    I did not change the color from the default black, but since the lines are different widths I believe the discrepancy can be easily observed.

    It would be my guess that whatever is not quite there would be in this part of the code:

    Code:
            Using p As New Pen(BorderColor)
                e.Graphics.DrawRectangle(p, 0, 0, Width - 1, Height - 1)
            End Using
    However, I know nothing about the code in the Using, so I am obviously only guessing. I am going to do some looking through whatever I can find on this, but if someone can explain to me what is going on it would be appreciated.

    Even with it not quite right and me not having any idea what to do (yet), this is still cool as hell!

  9. #9
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,274

    Re: Container line

    It looks like you have set BorderStyle to something other than None; probably FixedSingle. If you do that then the control will draw its own border first and reduce the usable area of the control by one pixel in all directions. Set BorderStyle back to None and then let the code I provided draw the border for you. Using FixedSingle for the BorderStyle will draw a single-pixel border but can't be any color but black.

  10. #10

    Thread Starter
    Fanatic Member
    Join Date
    Dec 2011
    Location
    Oregon City, Oregon
    Posts
    703

    Re: Container line

    You are absolutely correct. It is indeed set to FixedSingle. I set it to None and I do indeed get all for sides (or at least I will when I get the DGV that is sitting in it set to the right height). I am not sure I fully understand all of this (actually I damn sure don't), but I have to say JM, that this is cool as hell.

  11. #11
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,274

    Re: Container line

    The code I provided uses one of the fundamental principles of OOP: inheritance. When class B inherits class A, class B automatically has all the functionality of class A by default. You can then add extra functionality and/or depending on how it was implemented, modify existing functionality. That BorderedPanel does both.

    Pretty much every class you use in .NET inherits some other class. If you check out the documentation for a class, it will show you the inheritance hierarchy. For instance, the standard Panel control inherits ScrollableControl, which inherits Control, which inherits Component, which inherits MarshalByRefObject, which inherits Object, which is the root of the entire .NET type hierarchy.

    So, that BorderedPanel class automatically has all the functionality of the Panel class by default. If you were to use it without adding any more code, it would behave the same way exactly.

    It then adds the BorderColor property to enable you set the colour of the border. The property itself just stores a Color value, which is then used elsewhere to draw the border. More recently, VB.NET has supported auto-properties, which allows you to a property with a single line. I chose the old-style, full implementation (backing field, getter and setter) so that I could raise the BorderColorChanged event when the BorderColor property value changes. That's pretty much exactly how properties like Text are implemented to raise events like TextChanged.

    The .NET convention for raising SomeEvent is to use a method named OnSomeEvent. If you want to read more about that, follow the Blog link in my signature and check out my post on Custom Events. The OnBorderColorChanged method follows that convention. It raises the BorderColorChanged event and it also forces the control to be repainted, thus redrawing the border in the new colour.

    As per the convention I mentioned, the Control class has an OnPaint method to raise the Paint event. All GDI+ drawing on a control should be done on that event. In this case, the OnPaint method is overridden, i.e. a new implementation is provided. The base implementation of OnPaint is called first, which ensures that all existing functionality is executed, including actually raising the event and executing any event handlers. The border is then drawn as a rectangle around the edge of the control.

    All this means that, every time the control gets painted on screen, the last thing done will be to draw the border around the edge and over the top of anything else drawn in that area. It also means that the border will be redrawn whenever the BorderColor changes.

  12. #12

    Thread Starter
    Fanatic Member
    Join Date
    Dec 2011
    Location
    Oregon City, Oregon
    Posts
    703

    Re: Container line

    That is a really neat feature. However, I do believe I am going to have to put some time into all of that to really see and get real usage from it. But I can already see some of the possibilities.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width