Glinkot
Glinkot

Reputation: 2964

'Nice' options style winforms dialog control

Here and there I've seen nicely styled dialog controls, similar to this one which appears in Beyond Compare v4:

enter image description here

My own implementation of this gets vaguely close, and consists of a listbox on the left and usercontrols which change when the listbox selected item changes. However no amount of putting lipstick on that pig will get it looking like the above. I can picture how I might undertake this with custom painting of things and so forth, but my real intent is to generate the left hand entries at runtime not design time (there will be one for each column in a datafile).

I was wondering if anyone had any ideas on how to reasonably easily implement such a thing, either with a component (commercial is fine) or some other ingenious method.

Thanks!

Upvotes: 0

Views: 574

Answers (1)

TaW
TaW

Reputation: 54433

Here is an example of mimicking your design. I have one large panel1 to house both sides and in it one panel2 to house the left side. Inside panel2 there are the search controls and the listview.

The search controls are a Label1 containing a TextBox and another Label2. The Label.Images are aligned and the Textbox has no Border. The Labels are AutoSize=false and Label1 has a 3D-border.

Panel1 has a singleLine border, panel2 and the ListView have no borders. The ListView has View=Details and one column, HeaderStyle=None. It also has OwnerDraw=true.

I have added a Paint event for the ListView but have to call it in code.

Please note that I haven't taken the time to create nice images. Also note: Their height will determine the Items' Height (!) so leave a little transparent border above and below; their good looks will be key to the overall looks!

They are contained in an Imagelist with appropriate Size and BitDepth. You may need to adapt the DrawIamge numbers..

The stuff on the right side is pretty much standard; for the horizontal bar I use a Panel with height=1 and Border=Single. If you have more than one group of RadioButtons make sure to put each group in a separate Panel, transparent and no Borders, of course..

public Form1()
{
    InitializeComponent();

    listView1.Width = panel2.ClientSize.Width;
    listView1.Columns[0].Width = listView1.ClientSize.Width;
    listView1.Paint += listView1_Paint;
    listView1.BackColor = panel2.BackColor;
    leftBrush = new SolidBrush(panel2.BackColor);
    rightBrush = new SolidBrush(panel1.BackColor);
}

Pen borderPen = new Pen(SystemColors.ActiveBorder);
SolidBrush leftBrush, rightBrush;

private void listView1_DrawItem(object sender, DrawListViewItemEventArgs e)
{
    if (e.ItemIndex == 0)  listView1_Paint(
        null, new PaintEventArgs(e.Graphics, listView1.ClientRectangle)); 

    if (!e.Item.Selected)
    {
      e.Graphics.FillRectangle(leftBrush, e.Bounds);
      e.Graphics.DrawLine(borderPen, 
                 listView1.Width-1, e.Bounds.Y, listView1.Width-1, e.Bounds.Bottom);
    }
    else
    {
       e.Graphics.FillRectangle(rightBrush , e.Bounds);
       e.Graphics.DrawLine(borderPen, 0, e.Bounds.Top, e.Bounds.Width, e.Bounds.Top);
       e.Graphics.DrawLine(borderPen, 
                           0, e.Bounds.Bottom-1, e.Bounds.Width, e.Bounds.Bottom-1);
    }
    e.Graphics.DrawString( e.Item.Text, listView1.Font, 
                          Brushes.Black, 35, e.Bounds.Y + 5 );
    e.Graphics.DrawImage(imageList1.Images[e.Item.ImageIndex], 2, e.Bounds.Y );
}

void listView1_Paint(object sender, PaintEventArgs e)
{
    int hh = listView1.Items.Count * imageList1.ImageSize.Height;
    e.Graphics.DrawLine(borderPen, 
               listView1.Width - 1, hh, listView1.Width - 1, listView1.Height);
}

private void panel2_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.DrawLine(borderPen, panel2.Width-1, 0, panel2.Width-1, listView1.Top);
}

}

Here is a screenshot of my Q&D version:

'Nice' Options Dialog]

Upvotes: 3

Related Questions