- Thiết kế lại giao diện thể hiện của control
- Override lại các thuộc tính "Value" và "Text"
- Override lại sự kiện thường dùng là “ValueChanged”
- Thêm một vài thuộc tính mở rộng cho control.
Cách thức giải quyết vấn đề:
Tôi sử dụng bộ công cụ Visual Studio 2008 với ngôn ngữ là C# để viết control mở rộng này.
Bước đầu tôi tạo một Solution và đặt tên là ”DataTimePickerExtra” và sau đó chèn thêm một ClassLibrary project vào và cũng đặt tên giống như tên của Solution.
Bước thứ hai tiến hành xóa file tự sinh ra mặc định là Classe1.as và Add New Item một Comonent cũng với tên là “DataTimePickerExtra”.
Bước thứ 3 mở file “DataTimePickerExtra.cs” và thay đổi dòng sau:
…
public partial class DateTimePickerExtra : Component
…
thành
....
public partial class DateTimePickerExtra : DateTimePicker
....
và toàn bộ code giờ là như sau:
namespace DateTimePickerExtra
{
public partial class DateTimePickerExtra : DateTimePicker
{
public DateTimePickerExtra()
{
InitializeComponent();
}
public DateTimePickerExtra(IContainer container)
{
container.Add(this);
InitializeComponent();
}
}
}
Dòng code partial class DateTimePickerExtra : DateTimePicker thể hiện rằng Component này có kế thừa từ control DateTimePicker của dotnet.
Bước thứ tư bắt đầu tiến hành giải quyết các công việc ở trên.
*Thiết kể lại giao diện của control
Kết quả mà ta mong muốn ở đây là sẽ có một control giống hệt DateTimePicker ngoại trừ một khả năng mới. Đó là có thể hiển thị giá trị NULL trên giao diện, và đồng nghĩa với nó là có thể nhận giá trị null đầu vào. Do vậy Control mới cũng có khả năng nhập dữ liệu nhập tay của người dùng nhập vào.
Tôi nghĩ ra một cách giải quyết là chèn một TextBox control vào trong DateTimePicker và để TextBox đó che đi phần thể hiện text của control mẹ.
…
protected TextBox p_txtDateTime;
…
p_txtDateTime.ReadOnly = true;
p_txtDateTime.BackColor = Color.White;
//add the event for cath the key down and lost focus
p_txtDateTime.KeyDown+= new KeyEventHandler(p_txtDateTime_KeyDown);
p_txtDateTime.LostFocus += new EventHandler(p_txtDateTime_LostFocus);
//set the width of text box only cover the text on the DataTimePicker control
p_txtDateTime.Width = this.Width - 34;
p_txtDateTime.Top = -1;
this.Controls.Add(p_txtDateTime);
*Override các thuộc tính “Value” và “Text”
tiếp theo ta cần Override các thuộc tính quan trọng này
public new DateTime? Value
{
get
{
if (p_NullableValue)
{
if (string.IsNullOrEmpty(p_txtDateTime.Text))
return null;
}
return base.Value;
}
set
{
if (value != null)
base.Value = (DateTime)value;
else
p_txtDateTime.Text = string.Empty;
}
}
public override string Text
{
get
{
if (p_NullableValue)
{
if (onchangeValue)
{
onchangeValue = false;
return base.Text;
}
return p_txtDateTime.Text;
}
return base.Text;
}
set
{
base.Text = value;
p_txtDateTime.Text = value;
}
}
*Override sự kiện thường dùng “ValueChanged”.
protected override void OnValueChanged(EventArgs eventargs)
{
if (p_NullableValue)
{
if (!txtonchangeValue)
{
onchangeValue = true;
}
else
{
txtonchangeValue = false;
if (!string.IsNullOrEmpty(p_txtDateTime.Text))
onchangeValue = true;
}
p_txtDateTime.Text = this.Text;
}
base.OnValueChanged(eventargs);
}
*Thêm các thuộc tính mở rộng.
Tôi thêm vào một vài thuộc tính mở rộng để làm tăng tính linh hoạt của control mở rộng
protected bool p_AlertWrongDate = false;
protected bool p_NullableValue = true;
protected string p_ErrorMessage = "Invalid Date Format!";
p_AlertWrongDate: cho phép lựa chọn việc hiển thị thông báo lỗi khi người dùng nhập vào sai kiểu ngày tháng hay không
p_NullableValue: cho phép lựa chọn khả năng hiển thị giá trị NULL hoặc là không cho phép hiển thị( nếu bằng false thì control mở rộng sẽ lại giống như DateTimePicker của dotnet)
p_ErrorMessage: cho phép người dùng tùy biến thông điệp báo lỗi hiển thị ra.
Mã nguồn:
///
/// Show message box when input date not valid
///
public bool ShowError
{
get { return p_AlertWrongDate; }
set
{
if (!NullableValue)
{
p_AlertWrongDate = false;
}
else
{
p_AlertWrongDate = value;
}
}
}
///
/// Get or set NullableValue
///
public bool NullableValue
{
get { return p_NullableValue; }
set
{
p_NullableValue = value;
NullableValueChange();
}
}
///
/// Event will fire when the NullableValue changed
///
protected void NullableValueChange()
{
if (p_NullableValue)
{
p_txtDateTime.ReadOnly = true;
p_txtDateTime.BackColor = Color.White;
p_txtDateTime.KeyDown +=
new KeyEventHandler(p_txtDateTime_KeyDown);
p_txtDateTime.LostFocus +=
new EventHandler(p_txtDateTime_LostFocus);
p_txtDateTime.Width = this.Width - 34;
p_txtDateTime.Top = -1;
this.Controls.Add(p_txtDateTime);
initWidth = this.Width;
}
else if (this.Controls.Contains(p_txtDateTime))
{
this.ShowError = false;
this.Controls.Remove(p_txtDateTime);
}
}
///
/// Get or set ErrorMessage property
///
public string ErrorMessage
{
get { return p_ErrorMessage; }
set { p_ErrorMessage = value; }
}
Bên cạnh đó còn một vài phương thức hỗ trợ cho việc hoàn thiện control mở rộng này.
Và cuối cùng chúng ta có một control DateTimePickerExtra như hình dưới.
Các bạn có thể tham khảo mã nguồn theo link dưới đây.Download soucecode: http://www.mediafire.com/download.php?idm0ynw2idtxjkm