Wednesday, November 21, 2007

Outlook Style Groupbox Control

Introduction
This article explains very simple implementation of a outlook style groupbox. This control also supports transparent background.


Features
Following are the customizable things in this control
  • Groupbox border color
  • Back image or icon

Transparent background

This is achieved by using follwing code.
bool _isTransparent = false;
[Browsable(true), Category("Appearance")]
public bool IsTransparent
{
get { return _isTransparent; }
set
{
_isTransparent = value;
if (_isTransparent == true)
{
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.BackColor = Color.Transparent;
}
Invalidate();
}
}

Source Code (Download here)

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;

namespace Owf.Controls
{
public partial class OutlookGroupBox : Panel
{
[Browsable(true)]
public new string Text
{
get { return base.Text; }
set
{
base.Text = value;
Invalidate();
}
}

private Color _lineColor = SystemColors.Highlight;
[Browsable(true), Category("Appearance")]
public Color LineColor
{
get { return _lineColor; }
set
{
_lineColor = value;
Invalidate();
}
}

private Image _image;
[Browsable(true), Category("Appearance")]
public Image Image
{
get { return _image; }
set
{
if (value != null)
{
_image = value;
_icon = null;
Invalidate();
}
}
}

private Icon _icon;
[Browsable(true), Category("Appearance")]
public Icon Icon
{
get { return _icon; }
set
{
if (value != null)
{
_icon = value;
_image = null;
Invalidate();
}
}
}

bool _isTransparent = false;
[Browsable(true), Category("Appearance")]
public bool IsTransparent
{
get { return _isTransparent; }
set
{
_isTransparent = value;
if (_isTransparent == true)
{
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.BackColor = Color.Transparent;
}
Invalidate();
}
}

public OutlookGroupBox()
{
InitializeComponent();
SetStyles();
}

public OutlookGroupBox(IContainer container)
{
container.Add(this);
InitializeComponent();
SetStyles();
}

void SetStyles()
{
this.SetStyle(ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
}

private void OutlookGroupBox_Paint(object sender, PaintEventArgs e)
{
Font font = this.Font;
SizeF size = e.Graphics.MeasureString(this.Text, font);

e.Graphics.DrawString(this.Text, font, new SolidBrush(this.ForeColor), 1, 1);
e.Graphics.DrawLine(new Pen(_lineColor), size.Width + 3, (size.Height + 3) / 2,
this.Width - 5, (size.Height + 3) / 2);

if (_image != null)
{
e.Graphics.DrawImageUnscaled(_image, this.Padding.Left, this.Padding.Top);
}
else if (_icon != null)
{
e.Graphics.DrawIconUnstretched(_icon, new Rectangle(this.Padding.Left,
this.Padding.Top, _icon.Width, _icon.Height));
}
}
}
}

Tuesday, November 20, 2007

Test tốc độ trong .NET - System.Diagnostics.Stopwatch

System.Diagnostics.Stopwatch được sử dụng để xác định thời gian thực hiện một phương thức.

Lớp Stopwatch được xây dựng từ các API mức thấp. Nếu phần cứng và phiên bản Windows trên má tính hỗ trợ bộ đếm hiệu năng cao, nó sẽ sử dụng bộ đếm này thay cho đồng chuẩn của máy tính.

Đây là 1 ví dụ đơn giản:

System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();

watch.Start();

//do my stuff

...

watch.Stop();

MessageBox.Show("Time spent: " + watch.Elapsed.ToString());

?? operator (C#)

Toán tử ?? trả lại toán hạng bên trái nếu toán hạng này khác null, trả về giá trị bên phải trong trường hợp còn lại. Ví dụ:

int? x = null;

...

// y = x, nếu x khác null, khi x = null, y = -1.

int y = x ?? -1;

Toán tử ?? cũng làm việc với kiểu tham chiếu:

//message = param, nếu param khác null

//trong trường hợp param = null, message = "No message"

string message = param ?? "No message";

How to perform DateTime calculations in a right way

When coding, be careful if you need to perform DateTime calculations (add/subtract) on values representing time zones that practice daylight savings time. Unexpected calculation errors can result. Instead, convert the local time value to universal time, perform the calculation, and convert back to achieve maximum accuracy.

DateTime d;

d = DateTime.Parse("Oct 26, 2003 12:00:00 AM"); //date assignment

d = d.ToUniversalTime().AddHours(3.0).ToLocalTime();

//' - displays 10/26/2003 02:00:00 AM – Correct!

MessageBox.Show(d.ToString());

Working with DateTime structs seems to be simple, but it's not. Make sure you are aware of pitfalls discribed in the article Coding Best Practices Using DateTime in the .NET Framework.