Archive for April 2014

Thêm thuộc tính, sự kiện cho các điểu khiển trong winform

thuvienwinform - Apply Attributes in Windows Forms Controls (áp dụng các thuộc tính vào các điều khiển trong winform) sẽ giúp chúng ta thêm những sự kiện, thuộc tính chúng ta cần vào các control này. Ví dụ như thêm tính năng chuẩn hóa cho textBox, hoặc giới hạn độ dài cho textBox. Rất tiện trong quá trình code và sau này, tức là dùng cho được nhiều sản phẩm. Chính vì sự hữu ích này, hôm nay mình xin được chia sẻ cách thêm thuộc tính và sự kiện cho các điều khiển trong winform.


Tải về project demo: https://www.dropbox.com/s/6ih1d0oephk97r2/thuvienwinform-ThemThuocTinhChoControl.rar (46KB)

Bài viết này sẽ giới thiệu việc thêm tính năng chuẩn hóa và giới hạn độ dài cho TextBox. Gồm 2 phần
- Phần I: Thêm thuộc tính, sự kiện cho 1 điều khiển dựa trên lớp kế thừa
- Phần II: Tạo 1 điều khiển chứa nhiều điều khiển (từ các điều khiển đã có)

Chú ý: nếu tải về mở ra lỗi thì ấn F5 cho nó chạy sẽ hết lỗi (Do nó chưa nạp các điều khiển tự tạo vào)
- Để đọc code dễ ấn chuột phải vào code -> Outlining -> Collapse to Definitions (Ctrl + M,O).
- Để xem code của cotrol không có Design: ấn F7 hoặc ấn vào Switch to code...

I. Thêm thuộc tính, sự kiện cho 1 điều khiển

1. Thêm thuộc tính


- Rất đơn giản thôi. Đầu tiên thêm 1 class với tên: MyTextBox

- Class này kế thừa của TextBox


- Sau đó ta thêm các thuộc tính cho MyTextBox như sau:

[Category("Thuộc tính xây dựng thêm")]
[Description("Chuẩn hóa văn bản nhập vào. Viết hoa kí tự sau dấu cách")]
[DefaultValue(true)]
public bool ChuanHoa
{
    get;
    set;
}

private DoDai _doDai;//Cái này phục vụ cho việc thêm sự kiện sau này
[Category("Thuộc tính xây dựng thêm")]
[Description("Định độ dài cho văn bản \nNgắn: 30 kí tự\nBình thường: 60 kí tự\nDài:255 kí tự")]
public DoDai ĐộDài
{
    get { return _doDai; }
    set{_doDai = value;}
}

Với DoDai là 1 enum

public enum DoDai
{
    Ngắn,
    BìnhThường,
    Dài,
    TốiĐa
}

Trở lại phần thiết kế ta đã có được như này


2. Xây dựng chức năng chuẩn hóa, giới hạn độ dài

a. Chuẩn hóa
- Chúng ta sẽ chuẩn hóa sau khi nhập chữ vào MyTextBox xong. Sử dụng sự kiện LostFocus và ấn nút Enter để thực hiện chuẩn hóa. this.Text = ChuanHoaXau(this.Text);

protected override void OnLostFocus(EventArgs e)
{
    base.OnLostFocus(e);
    ThucHienChuanHoa();
}

protected override void OnKeyDown(System.Windows.Forms.KeyEventArgs e)
{
    base.OnKeyDown(e);
    //Ấn enter
    if (e.KeyCode == System.Windows.Forms.Keys.Enter)
        ThucHienChuanHoa();
}

private void ThucHienChuanHoa()
{
    //Chuẩn hóa xâu trong textBox
    this.Text = ChuanHoaXau(this.Text);//Các hàm còn lại xem trong project demo nha
    //Đưa con trỏ nhấp nháy về cuối dòng
    this.Select(this.Text.Length, this.Text.Length);
}

Kết quả:


b. Giới hạn độ dài
- Để giới hạn độ dài ta sử dụng sự kiện TextChanged
protected override void OnTextChanged(EventArgs e)
{
    base.OnTextChanged(e);
    int doDaiToiDa = 0;
    switch (ĐộDài)
    {
        case DoDai.Ngắn         : doDaiToiDa = 30; break;
        case DoDai.BìnhThường   : doDaiToiDa = 60; break;
        case DoDai.Dài          : doDaiToiDa = 255; break;
        default: break;
    };
    if (ĐộDài != DoDai.TốiĐa)
        if (this.Text.Length > doDaiToiDa)
            ThietLapDoDai(doDaiToiDa);
}

/// <summary>
/// Thiết lập độ dài kí tự trong textBox
/// </summary>
/// <param name="ddtd">Độ dài tối đa cho phép</param>
private void ThietLapDoDai(int ddtd)
{
    //Dữ lại đoạn văn bản cho phép
    this.Text = this.Text.Substring(0, ddtd);
    //Đưa con trỏ nhấp nháy về cuối dòng
    this.Select(ddtd, ddtd);
}

- Cách này khá thủ công như có lẽ như vậy sẽ dễ hiểu hơn. Để tối ưu thì ta sửa luôn việc set get biến Text của TextBox. Chuẩn hóa luôn khi set get

3. Bắt sự kiện thay đổi giá trị ĐộDài

a. Sử dụng delegate EventHandler
- Tạo sự kiện
public event EventHandler ThayDoiDoDai;//Khai báo sự kiện

- Code cho sự kiện
protected virtual void OnThayDoiDoDai()
{
    EventHandler handler = this.ThayDoiDoDai;
    if (handler != null)
    {
        handler(this, EventArgs.Empty);
    }
}

- OK. Đã có sự kiện! Bây giờ đặt vào chỗ cần thực hiện sự kiện. Đó là khi giá trị ĐộDài thay đổi. Là lúc nào nhỉ?? Chính là lúc set get giá trị cho nó
public DoDai ĐộDài
{
    get { return _doDai; }
    set
    {
        _doDai = value;
        //Mỗi khi thay đổi giá trị -> set, get 1 lần => chính là sự kiện thay đổi giá trị
        OnThayDoiDoDai();
    }
}


b. Tạo lớp kế thừa của EventHandler để tạo thêm các giá trị cho sự kiện
- Ví như sự kiện CellClick của DataGridView có thể lấy giá trị hàng (e.RowIndex). Vậy làm như thế nào để thêm các thuộc tính cho sự kiện. Ta cần tạo 1 lớp kế thừa của thằng EventHandler như sau:
//Tạo class bằng file mới hoặc trong cùng class MyTextBox đều được. Xem thêm trong project demo
public class ThayDoiGiaTriDoDai : EventArgs
{
    public DoDai GiaTriDoDai { get; set; }
    public bool DuocChuanHoa { get; set; }
    public string ThongTinChoSuKien
    {
        get { return "Sự kiện thay đổi giá trị độ dài của MyTextBox"; }
    }
}

- Thêm sự kiện sử dụng lớp kế thừa này
[Category("Sự kiện Xây dựng thêm")]
[Description("Bắt sự kiện thay đổi độ dài. Dùng class kế thừa")]
public event EventHandler<ThayDoiGiaTriDoDai> ThayDoiDoDaiDungClass;//Khai báo sự kiện
/// <summary>
/// Code cho sự kiện
/// </summary>
/// <param name="s">Nạp giá trị đầu vào để hiển thị ra khi sử dụng sự kiện</param>
protected virtual void OnThayDoiDoDai(ThayDoiGiaTriDoDai s)
{
    EventHandler<ThayDoiGiaTriDoDai> handler = this.ThayDoiDoDaiDungClass;
    if (handler != null)
    {
        handler(this, s);
    }
}

- OK bây giờ sửa lại lúc set get là được
public DoDai ĐộDài
{
    get { return _doDai; }
    set
    {
        _doDai = value;
        //Mỗi khi thay đổi giá trị -> set, get 1 lần => chính là sự kiện thay đổi giá trị
        SuKien = new ThemThuocTinhChoControl.ThayDoiGiaTriDoDai();
        SuKien.GiaTriDoDai = this.ĐộDài;
        SuKien.DuocChuanHoa = this.ChuanHoa;
        OnThayDoiDoDai(SuKien);
    }
}

- Kết quả:



II. Tạo UserControl từ các control khác

- Trong thực tế có nhiều form ta có các kiểu bố trí giống nhau, có sự kết hợp của nhiều control giống nhau. Ví dụ như tập hợp các textBox để nhập thông tin họ tên ngày sinh,...thì ta chỉ cần tạo 1 lần vào sử dụng cho các form khác nhau. Để thực hiện việc này ta làm như sau:

- Tạo 1 UserControl

- Sau đó thì kéo các điều khiển khác vào

- Ok có thể nói là xong rùi nhưng ta muốn thêm các thuộc tính, sự kiện cho thằng này thì làm tương tự phần I là OK.
- Ví dụ thêm thuộc tính tự động Anchor:
public bool TuDongDanCachCacPhanTu
{
    get { return _tuDongDanCachCacPhanTu; }
    set 
    { 
        _tuDongDanCachCacPhanTu = value;
        if (_tuDongDanCachCacPhanTu)
        {
            this.Anchor = AnchorStyles.Bottom | AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;//This ở đây là UserCOntrol
            this.myTextBox1.Anchor = AnchorStyles.Bottom | AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
            this.myTextBox2.Anchor = AnchorStyles.Bottom | AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
        }
        else
        {
            this.Anchor = AnchorStyles.Top | AnchorStyles.Left;
            this.myTextBox1.Anchor = AnchorStyles.Top | AnchorStyles.Left;
            this.myTextBox2.Anchor = AnchorStyles.Top | AnchorStyles.Left;
        }
    }
}
- Sau khi đã thêm tạo được các file cs chỉ cần thêm vào các project khác là ok.

Nếu thấy hữu ích hãy để lại bình luận hoặc ấn G+. Cảm ơn các bạn đã đọc bài viết
4/25/2014
Đăng bởi :

LINQ to Sqlite, LINQ to MySQL, LINQ to Oracle

thuvienwinform - SQLite mà mình thấy nó quá tuyệt với rồi! Bây giờ lại phát hiện ra bộ kết nối giữa C# với SQLite bằng LINQ nữa, tốc độ code phải tăng gấp 10 lần mất, không tù tội như hồi trước xài ADO.NET nũa (nói thế hơi quá nhưng ADO.NET phải chạy mới biết lỗi). Nó chính là bộ LinqConnect. Các bạn có thể tải về bản đầy đủ tất cả LINQ to X với X = {SQLite, MySQL, Oracle,...} :D. Việc sử dụng tương tự như LINQ to SQL, cũng kéo thả, sinh code tự động.


Tải về (44MB):
- Dropbox: https://www.dropbox.com/s/bo88kvu7b6s2w8a/linqconnectfree.exe
- MediaFire: http://www.mediafire.com/download/2sjr3jxegugb1t1/linqconnectfree.exe

Trước khi cài thoát Visual Studio ra nha. Sau khi cài xong thì add item nó sẽ có cái này:


Tạo CSDL bằng SQLite: http://thuvienwinform.blogspot.com/2013/10/SQLite-chay-ung-dung-su-dung-da-tabase-tren-may-khong-cai-sql.html

Hướng dẫn: http://www.devart.com/dotconnect/sqlite/articles/tutorial_linq.html#model

Chú ý khi sử dụng
- Nhập đúng namspace. Bình thường cứ quen tay next next là hỏng đấy :D



Còn việc thêm, sửa, xóa thì giống hệt trong LINQ to SQL:
- Nạp, thêm dữ liệu: http://thuvienwinform.blogspot.com/2014/01/linq-to-sql-bai-1-load-va-them-du-lieu.html
- Sửa dữ liệu: http://thuvienwinform.blogspot.com/2014/01/linq-to-sql-bai-2-sua-du-lieu.html
- Xóa dữ liệu: http://thuvienwinform.blogspot.com/2014/01/linq-to-sql-bai-3-xoa-du-lieu.html

Chú ý:
Muốn sang máy khác chạy được cần copy toàn bộ thư viện (các tệp .dll) gồm:
1. Phần tự sinh của Devart

Devart.Data.dll
Devart.Data.Linq.dll
Devart.Data.SQLite.dll
Devart.Data.SQLite.Linq.dll
2. Phần lấy trong ổ cài của Devart: (mặc định: C:\Program Files (x86)\Devart\dotConnect\SQLite)
sqlite3.dll
thư mục x64

Tổng cộng bằng này cái:
Nếu không đủ sẽ gặp một số lỗi về như DbCommand..., version asembly...balabala

4/20/2014
Đăng bởi :
Nhãn : ,

CHAT LAN C#. Phần 3: Code máy khách (Client). Gửi, nhận dữ liệu với máy chủ

thuvienwinform - Sau khi đã có máy chủ thì chỉ việc tạo các máy khách kết nối đến máy chủ để giao tiếp với nhau thui. Sau khi tạo được kết nối thì máy khách sẽ gửi dữ liệu đến máy chủ và nhận dữ liệu truyền về! Đơn giản hơn code trên máy chủ rất nhiều.

Tải về project: https://www.dropbox.com/s/3moekk8knkge5s4/thuvienwinform-CHATLANClient.rar (18KB)

Yêu cầu:
- Kết nối chung mạng với máy cái ChatLanServer.
- Máy khách không cần Ip tĩnh

Cụ thể các bước xây dựng một máy khách như sau:
1/ Tạo luồng kết nối TcpClient
2/ Kết nối đến máy chủ với địa chỉ ip và cổng xác định (là ip tĩnh và cổng được tạo cho chương trình ChatLanServer trên máy chủ)
3/ Thực hiên giao tiếp với máy chủ
4/ Đóng kết nối

Các biến:

//Địa chỉ mặc định
string IP = "127.0.0.1";
int PORT = 100;

//Các luồng
Thread thKetNoiDenServer, thKetNoiTaoServer;

//Biến dùng để gửi, nhận dữ liệu
byte[] dlNhan = new byte[1024];
byte[] dlGui = new byte[1024];

TcpClient Khach;


1/ Tạo luồng kết nối TcpClient

Khach = new TcpClient();

2/ Kết nối đến máy chủ với địa chỉ ip và cổng xác định

Khach.Connect(IPAddress.Parse(IP), PORT);

3/  Thực hiên giao tiếp với máy chủ

- Nhận dữ liệu: TcpClient.GetStream().Read

string tmp = "";
byte[] dlNhan = new byte[1024];
Khach.GetStream().Read(dlNhan, 0, 1024);
tmp = Encoding.Unicode.GetString(dlNhan);

- Gửi dữ liệu: TcpClient.GetStream().Write

byte[] dlGui = new byte[1024];
dlGui = Encoding.Unicode.GetBytes(txtGui.Text);
Khach.GetStream().Write(dlGui, 0, dlGui.Length);

4/ Đóng kết nối

Thêm mô tả tìm kiếm và Liên kết cố định để SEO chuẩn :)
 
Khach.Close();



Nếu bạn mua IP tĩnh thì nó trở thành chat online là truyện bình thường :) cho máy cài IP tĩnh đó chạy chương trình server và các máy khách kết nối đến là được

19-5-2015:
Thực ra với C# có nhiều cách để xây dựng một ứng dụng truyền dữ liệu qua mạng kiểu này. Sử dụng socket là cái nền tảng sơ khai nhất, mình sẽ hướng dẫn một bài khác cũng về vấn đề truyền dữ liệu qua mạng này trên một công nghệ khác (WCF hoặc Remote) đơn giản hơn nhiều, các bạn theo dõi blog để nhận bài sớm nhất nhé!
4/19/2014
Đăng bởi :
Nhãn : ,

CHAT LAN C#. Phần 2: Code máy chủ (Server). Xử lí việc gửi nhận với nhiều máy khách

thuvienwinform - Để thực xây dựng chương trình gửi tin nhắn qua mạng LAN cần có một chương trình chạy trên máy chủ. Chức năng chính của nó là: Nhận kết nối từ các máy khách, sau khi tạo được kết nối thì bắt đầu việc gửi/nhận dữ liệu giữa máy chủ và máy khách. Khi nhận được dữ liệu (văn bản, hình ảnh, âm thanh,..) thì sẽ được xử lí trên máy chủ này. Có thể là lưu vào CSDL hoặc thực hiện các lệnh nhận được từ máy khách như gửi cho họ một tài liệu, hình ảnh, đoạn phim,...

Phần 1: [CHAT LAN] Phần 1: Giao thức TCP và System.NET. Những thành phần côt yếu để xây dựng chương trình chat qua mạng LAN

Tải project: https://www.dropbox.com/s/tydku6em1cjq8mb/thuvienwinform-CHATLANServer.rar (21KB)




Máy chủ dùng IP hiện tại của máy. Tham khảo thêm cách lấy IP này: http://thuvienwinform.blogspot.com/2013/10/code-lay-username-va-ip-cua-may.html


Cụ thể thì các bước để xây dựng một máy chủ như sau:
1/ Tạo (mở) một cổng kết nối logic (socket) để cho các máy khách tham gia gửi/nhận tin băng cổng này
2/ Đợi, lắng nghe và chấp nhận các kết nối từ máy khách
3/ Thực hiên giao tiếp với máy khách: Nhận dữ liệu từ máy khách, phân tích, xử lí sau đó gửi lại co máy khách. (lưu vào CSDL, chống nói tục@!, ...)
4/ Đóng socket



- Các code chat mạng LAN trên mạng thường thì bước 2 chỉ chấp nhận được 1 kết nối. Để chấp nhận nhiều kết nối thì ta cho bước 2 vào vòng lặp, khi kết nối thêm 1 khách sẽ chuyển bước 3 sang 1 luồng (thread) khác giao tiếp với máy khách đó.

- Trong này sử dụng khá nhiều về thread. Có thể xem thêm ở bài Thread trong C#: http://thuvienwinform.blogspot.com/2014/04/thread-trong-csharp.html


Các biến:

//Địa chỉ mặc định
string IP = "127.0.0.1";
int PORT = 100;

//Các luồng
Thread thKetNoiDenServer, thKetNoiTaoServer, thLienLacKhach;
TcpListener langNghe;

//Biến dùng để gửi, nhận dữ liệu
byte[] dlNhan = new byte[1024];
byte[] dlGui = new byte[1024];

//Socket tạo server và kết nối
Socket socket;
//Tạo 1 socket
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//Danh sách các máy khách kết nối đến
List cacMay = new List();

1/ Tạo (mở) một cổng kết nối logic (socket)

//Tạo 1 socket
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint iep = new IPEndPoint(IPAddress.Parse(IP), PORT);//IP = "127.0.0.1"; PORT = 100;
//Liên kết cổng s với địa chỉ IP và cổng
s.Bind(iep);
//Nhận tín hiệu từ các máy kết nối
s.Listen(10);

Nếu có 1 IP tĩnh mua với nhà mạng thì chương trình này trở thành chat online luôn đó :)
2/ Đợi, lắng nghe và chấp nhận các kết nối từ máy khách


//Thêm máy khách
socket = s.Accept();

//Lưu máy khách được thêm vào danh sách. Để dễ quản lí
cacMay.Add(socket);

//Thông báo kết nối với máy khách
txtNoiDung.Text = txtNoiDung.Text + "Đã thêm 1 máy khách " + "\r\n";

//Mỗi máy khách sẽ được xử lí trong 1 luồng (thread)
ThreadPool.QueueUserWorkItem(GiaoTiepTungKhach, socket);

với List cacMay = new List();
Cài tiến code bước 2 này để nhận được kết nối từ nhiều máy khách:

//Trong khi còn kết nối. Mỗi khi có tín hiệu từ máy khách đến sẽ thêm vào -> nhận đc nhiều máy khách cùng lúc
while (true)
{
    //Thêm máy khách
    socket = s.Accept();

    //Lưu máy khách được thêm vào danh sách. Để dễ quản lí
    cacMay.Add(socket);

    //Thông báo kết nối với máy khách
    txtNoiDung.Text = txtNoiDung.Text + "Đã thêm 1 máy khách " + "\r\n";

    //Mỗi máy khách sẽ được xử lí trong 1 luồng (thread)
    ThreadPool.QueueUserWorkItem(GiaoTiepTungKhach, socket);
}


3/ Thực hiên giao tiếp với máy khách

- Nhận văn bản gửi đến lưu vào biến tạm tmp

string tmp = "";
byte[] dlNhan = new byte[1024];
socket.Receive(dlNhan);
tmp = Encoding.Unicode.GetString(dlNhan);

- Gửi văn bản đến các máy khách:

foreach (Socket s in cacMay)
{
    s.Send(Encoding.Unicode.GetBytes(noiDung));
}

Để gửi được hình ảnh thì ta chuyển ảnh thành byte[] xong cũng gửi bình thường. Xem cách chuyển: http://thuvienwinform.blogspot.com/2014/03/code-up-anh-len-csdl-su-dung-kieu-image-trong-sqlserver.html
4/ Đóng socket


Khach.Close();


Để chương trình hoạt động thì ngày mai sẽ có project máy khách cho các bạn nha :)
19-5-2015: Thực ra với C# có nhiều cách để xây dựng một ứng dụng truyền dữ liệu qua mạng kiểu này. Sử dụng socket là cái nền tảng sơ khai nhất, mình sẽ hướng dẫn một bài khác cũng về vấn đề truyền dữ liệu qua mạng này trên một công nghệ khác (WCF hoặc Remote) đơn giản hơn nhiều, các bạn theo dõi blog để nhận bài sớm nhất nhé!
4/18/2014
Đăng bởi :
Nhãn : ,

CHAT LAN C#. Phần 1: Giao thức TCP và System.NET. Những thành phần côt yếu để xây dựng chương trình chat qua mạng LAN

thuvienwinform - C# hỗ trợ chúng ta lập trình mạng rất tốt, cụ thể là có thư viện System.Net. Qua đó chúng ta có thể xây dựng những ứng dụng hữu ích để gửi, nhận dữ liệu qua mạng. Một ví dụ điển hình cho việc lập trình mạng là chương trình gửi tin nhắn (chat) qua mạng LAN. Cũng đơn giản thui từ từ từng bước một là OK. Để xây dựng chương trình này trước hết chúng ta cần tìm hiểu về giao thức hoạt động để gửi/nhận dữ liệu TCP và System.NET

1. TCP

Wikipedia:
- TCP là giao thức cốt lõi của bộ giao thức TCP/IP. Sử dụng TCP, ử dụng TCP, các ứng dụng trên các máy chủ được nối mạng có thể tạo các "kết nối" với nhau, mà qua đó chúng có thể trao đổi dữ liệu hoặc các gói tin. Giao thức này đảm bảo chuyển giao dữ liệu tới nơi nhận một cách đáng tin cậy và đúng thứ tự. TCP còn phân biệt giữa dữ liệu của nhiều ứng dụng (chẳng hạn, dịch vụ Web và dịch vụ thư điện tử) đồng thời chạy trên cùng một máy chủ. Xem thêm...
- TCP hỗ trợ nhiều giao thức ứng dụng phổ biến trên Internet và các ứng dụng kết quả như www, thư điện tử,...
- TCP như kiểu 2 hay nhiều người nói chuyện với nhau. Một người  hỏi: "Mày có nghe rõ không" nếu thằng kia trả lời "Có" thì mới thực hiện trò chuyện. Vì vậy TCP đảm bào việc truyền dữ liệu

- Mỗi máy tính có một địa chỉ IP => phân biệt các máy qua địa chỉ IP. Mỗi chương trình trên máy có một cổng kết nối => phân biết các chương trình bằng cổng kết nối. => để gửi dữ liệu cho một chương trình trên máy tính cần có địa chỉ ip của máy và cổng của chương trình đó

- Ngoài TCP thì trong bộ giao thức TCP/IP còn có thêm giao thức UDP. Cái này nó truyền tín hiệu nhanh hơn TCP nhưng tín hiệu truyền đi lại được cho phép mất, không biết thèn kia có nhận được hay chưa. Bù lại thì nó truyền nhanh hơn. Như trong ví dụ 2 thằng nói truyện ở trên, với UDP thì không cần thằng kí trả lời có ta vẫn cứ nói, mặc kệ có nghe tao hay không :D. Giống như kiểu gửi email cho 1 thằng offline, không biết nó có nhận và đọc hay không

- Tài liệu về giao TCP và IP:  https://docs.google.com/document/d/1GR39aiMkP1giKa9Brppbc9loHB2YaQ5QjD0ZX_M2YLo/edit?hl=en

2. System.NET


- Để xây dựng chương trình chat qua mạng LAN ta cần sử dụng: IPEndPoint, Socket, TcpClient, IPAdress

Ở phần tiếp thuvienwinform sẽ mang đến project dành cho máy chủ trong chương trình chat qua mạng LAN.

19-5-2015:
Thực ra với C# có nhiều cách để xây dựng một ứng dụng truyền dữ liệu qua mạng kiểu này. Sử dụng socket là cái nền tảng sơ khai nhất, mình sẽ hướng dẫn một bài khác cũng về vấn đề truyền dữ liệu qua mạng này trên một công nghệ khác (WCF hoặc Remote) đơn giản hơn nhiều, các bạn theo dõi blog để nhận bài sớm nhất nhé!

Thread trong C#

thuvienwinform - Thread cho phép thực hiện cùng lúc nhiều công việc song song với nhau mà không bị đơ, lag (lác :D), gián đoạn. Nó đặc biệt quan trọng trong lập trình mạng, các ứng dụng đỏi hỏi thực hiện công việc nặng nhọc, duyệt vòng lặp lớn (lặp vài trăm nghìn lần như duyệt các thư mục), nếu không dùng thread thì chương trình sẽ không thể tương tác được, có thể rơi vào trạng thái không phản hồi (Not Responding - Cái này quen quen). Nhờ có Thread mà ứng dụng trở nên mượt hơn, hạn chế đơ, lag, sử dụng CPU hiệu quả hơn với lập trình winform.



- Để sử dụng thread ta khai báo using System.Threading;
- Số thread tối đa cho 1 chương trình:
+ Với .NET2.0 là 25.
+ Với .NET3.5 là 250.
+ Với .NET4.0 (32bit) là 1023.
+ Với .NET4.0 (64bit) là 32768.
+...

1/ Tạo thread mới để chạy 1 hàm, thủ tục
- Cho hàm, thủ tục không có tham số truyền vào

Thread t1;
t1 = new Thread(ThuTuc1);
với ThuTuc1 là một thủ tục (void) không có tham số truyền vào

Các ví dụ dưới đây sẽ dùng thread t1 này là ví dụ ạ

- Cho hàm, thủ tục có tham số truyền vào (Sử dụng Lambda Expresstion)

t1 = new Thread();
t1 = new Thread((ThreadStart) =>
    {
        ThuTuc2("Truyen vao");
    });
2/ Chạy thread đó
- Sau khi tọa được thread rùi ta có thể cho nó bắt đầu chạy:

t1.Start();

3/ Dừng thread

t1.Abort();

4/ Tạm dừng thread

t1.Suspend();
Tạm dừng cho đến khi
t1.Resume();


5/ Mức độ ưu tiên của thread (Thread Priority)
- Khi sử dụng nhiều thread thì ta cài đặt độ ưu tiên thực thi của các thread

t1.Priority = ThreadPriority.Lowest;
- Có các giá mức ưu tiên: Lowest, BelowNormal, Normal, AboveNormal, Hightest


6/ Join
- Cái này nó sẽ làm như sau: Những thread dưới câu lệnh Join() sẽ được start sau khi các thread trên câu lệnh join chạy xong

7/ Thoát chương trình nhưng thread vẫn chạy
- Thread có 2 loại: ForeGround và BackGround.
+ Chương trình sẽ tắt khi các ForeGround thread chạy xong
+ Còn các BackGroud Thread sẽ dừng lại khi tắt chương trình.

- Lí do là khi ta tạo 1 thread nó mặc định là loại ForeGround
- Để khi tắt chương trình các thread cũng dừng thì ta sẽ chuyển các thread sang BackGround như sau:

t1.IsBackground = true;
t1.Start();
Chuyển thread thành background trước khi start

8/ Thread Pooling
- Cái này hơn rất rất nhiều. Có thể nói nó tối ưu thread.
- Thread Pooling mặc định là loại BackGround
- Sau khi kết thúc một tác vụ nó sẽ trở về trạng thái sẵn sàng nhận một nhiệm vụ mới
- Chạy một thủ tục, hàm bằng Thread Pooling (thủ tục, hàm phải có đầu vào là 1 Object)

private void Button1_Click()
{
    ThreadPool.QueueUserWorkItem(ThreadPooling, "Test");
   //Hoặc: ThreadPool.QueueUserWorkItem(ThreadPooling);
}
private void ThreadPooling(object obj)
{
    MessageBox.Show(obj.ToString());
}

Nguồn: YinYang's Blog

[ENCODING] Chuyển đổi qua lại giữa các loại mã (Unicode-UTF8-UTF7-ASCII...)

Chào !
Hôm nay mình sẽ hướng dẫn các bạn chuyển đổi các loại mã (Unicode-UTF8-UTF7-ASCII...)
Các bạn có thể hoàn toàn tạo được 1 tool giúp chuyển đổi các loại mã trong Văn bản ^^!
(Ví dụ bạn dùng MS Word đã lỡ dùng Unicode nhưng người ta yêu cầu phải dùng định dạng ASCII hết chẳng hạn ... )

OK. Bắt đầu nhé !
Ở đây mình sẽ ví dụ chuyển mã Unicode sang mã UTF8 :

1. Hãy "using System.Text" để sử dụng lớp Encoding

2. Chuyển dữ liệu về mảng byte :

// Chuyển string szDuLieuUniCode về dạng mảng byte
byte[] unicode = Encoding.Unicode.GetBytes(szDuLieuUniCode);
// Cover byte unicode sang byte utf8
byte[] utf8 = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, unicode);
// chuyển từ mảng byte utf8 về dạng string
string szDuLieuUTF8 = Encoding.UTF8.GetString(utf8);

OK Vậy là đã xong !
4/17/2014
Đăng bởi :
Nhãn :

[API] Ini - Ghi các setting cực tốt !

Với một phần mềm có chức năng tùy chỉnh thì việc lưu các setting là rất quan trọng.
Hôm nay mình xin hướng dẫn các bạn một trong các kiểu ghi/đọc các setting cực kì phổ biến -- Đọc/Ghi Ini

1. Tổng quan một file ini
1 file được ghi theo kiểu Ini sẽ có dạng sau đây :
[Section]
Key=Value

Ví dụ mình muốn lưu cái "Tự động đăng nhập" cho phần mềm của mình thì File ini sẽ có dạng sau :
[TuDongDangNhap]
KichHoat=1
TaiKhoan=buiducduy111

2. Thực hiện trong C#

2.1 . Đừng quên " using System.Runtime.InteropServices;" để có thể sử dụng các hàm API
2.2. Sử dụng DLL :  kernel32

[DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filepath);
        [DllImport("kernel32")]
        private static extern long GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filepath);

OK vậy là bạn có thể Đọc/Ghi dữ liệu từ file setting theo cách trên

Nếu chưa làm được hãy xem code dưới đây (Bạn chỉ cần sử dụng INI.READ và INI.WRITE thôi)
public class INI
    {
        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filepath);
        [DllImport("kernel32")]
        private static extern long GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filepath);

                      // Viết thêm 2 hàm mới cho dễ  
        public static string READ(string szFile, string szSection, string szKey)
        {
            StringBuilder tmp = new StringBuilder(255);
            long i = GetPrivateProfileString(szSection, szKey, "", tmp, 255, szFile);
            return tmp.ToString();
        }
        public static void WRITE(string szFile, string szSection, string szKey, string szData)
        {
            WritePrivateProfileString(szSection, szKey, szData, szFile);
        }
    }

3. Thực hành
Ví dụ : (Sử dụng class INI được xây dựng bên trên)
INI.WRITE("Data.ini","TuDongDangNhap","TaiKhoan", "buiducduy");
INI.WRITE("Data.ini","TuDongDangNhap","KichHoat", "1");
Kết quả trong Data.ini :
[TuDongDangNhap]
TaiKhoan=buiducduy111
KichHoat=1

string s = INI.READ("Data.ini","TuDongDangNhap","TaiKhoan");
MessageBox.Show(s);
Kết quả "buiducduy";

OK. Nếu chưa hiểu bạn cứ comment ở dưới nhé!

4/14/2014
Đăng bởi :
Nhãn : ,

[SOFTWARE DESIGN] Thiết kế phần mềm theo mô hình 3 lớp Layer

Hướng tới lập trình chuyên nghiệp (nói cho oai chứ mình gà lắm) - không chỉ về mặt code , thuật toán ... mà bạn cần phải thiết kế phần mềm sao cho dễ chỉnh sửa , cập nhật nhất (nhất là đối với code team và bạn đã định hướng phát triển phần mềm lâu dài)

Hôm nay mình xin giới thiệu một cách thiết kế khá phổ biết là "MÔ HÌNH 3 LỚP LAYER"

1. Giới thiệu tổng quan
Như tên của mô hình. Chúng ta sẽ thiết kế phần mềm theo 3 lớp sau :
- GUI Layer : chuyên xử lí về GUI (giao diện)
- Business Layer : chuyên xử lí về nghiệp vụ, thuật toán....
- Data Access Layer : đưa dữ liệu xuống cơ sở dữ liệu cũng như lấy dữ liệu từ cơ sở dữ liệu lên

Ngoài ra chúng ta dùng thêm 1 class là : Data Transfer Object (DTO) có chức năng là cầu nối giữa các Layer. (Ta cũng có thể dùng các parameter để truyền dữ liệu , tùy nhiên nhiều parameters quá thì nên dùng tên class này)

2. Các bước thiết kế phần mềm theo mô hình 3 lớp layer
Bây giờ chúng ta cùng nhau thiết kế một phần mềm đơn giản nhé ^^

Để đơn giản ở đây tôi không dùng hệ quản trị cơ sở dữ liệu mà ghi dữ liệu ra file "Data.txt"  (Coi như nó là DataBase đi :D -- File này sẽ chỉ ghi được 1 tài khoản thôi nhưng đây là ví dụ mà -- các bạn có thể áp dụng vào các hệ quản trị CSDL giống như vậy)

- Thiết kế một GUI như sau :
GUI có 2 textbox : txtTaiKhoan và txtMatKhau và một button : btnDangKi

- Tạo các Folder vào các class như hình dưới đây :
(GUI Layer : frmRegister.cs | Business Layer : XuLi.cs | Data Access Layer : VanChuyenDuLieu.cs
và DTO.cs)
- OK Tiến hành code nhé :

** DTO.cs (Nơi đây chỉ chứa các biến vận chuyển) :

namespace MOHINH3LOPLAYER
{
    public class DTO
    {
        private string _TaiKhoan;
        private string _MatKhau;
        public string TaiKhoan
        {
            set {_TaiKhoan = value;}
            get {return _TaiKhoan;}
        }
        public string MatKhau
        {
            set {_MatKhau = value;}
            get {return _MatKhau;}
        }
    }
}


**VanChuyenDuLieu.cs (Nơi đây chỉ có chức năng đọc/ghi dữ liệu xuống CSDL)
Ở phương thức GhiDuLieu tôi sẽ truyền vào đối tượng DTO
namespace MOHINH3LOPLAYER.Data_Access_Layer
{
    public class VanChuyenDuLieu
    {
        public static void GhiDuLieu(DTO doituong)
        {
            FileStream fs = new FileStream("Data.txt", FileMode.Create, FileAccess.ReadWrite, FileShare.None);
            StreamWriter sw = new StreamWriter(fs);
            sw.WriteLine(doituong.TaiKhoan);
            sw.WriteLine(doituong.MatKhau);
            sw.Flush();
            sw.Close();
        }
    }
}
** XuLi.cs (Nơi đây chỉ có chức năng xử lí thuật toán)

namespace MOHINH3LOPLAYER.Business_Layer
{
    public class XuLi
    {
        private static bool KiemTra(DTO doituong)
        {
            if (doituong.TaiKhoan != "" && doituong.MatKhau != "")
                return true;
            return false;
        }
        public static bool DangKi(DTO doituong)
        {
            if (!KiemTra(doituong))
                return false;
            MOHINH3LOPLAYER.Data_Access_Layer.VanChuyenDuLieu.GhiDuLieu(doituong);
            return true;
        }
    }
}

** Và cuối cùng là Xử lí nút "Đăng kí ở GUI" như sau :

private void btnDangKI_Click(object sender, EventArgs e)
        {
                         // Tạo đối tượng DTO
            DTO doituong = new DTO();
            doituong.TaiKhoan = this.txtTaiKhoan.Text;
            doituong.MatKhau = this.txtMatKhau.Text;

            if (MOHINH3LOPLAYER.Business_Layer.XuLi.DangKi(doituong))
            {
                MessageBox.Show("Đăng kí thành công");
            }
            else
            {
                MessageBox.Show("Đăng kí thất bại");
            }
        }

OK như vậy là xong ^^! Đơn giản đúng không :D

Đăng bởi :

Code quay lui bằng C# tìm tổ hợp, chỉnh hợp chập k của n

thuvienwinform - Thuật toán trâu bò quen thuộc và khá hữu ích trong việc code. Để tìm tổ hợp đơn giản là tìm một dãy số thỏa mãn điều kiện sau:
- Các số đều khác nhau
- Số sau lớn hơn số trước
- Các bộ số không trùng lặp nhau
-...

 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;

namespace QuayLuiTimToHop
{
    class Program
    {
        #region Khai báo
        static int n, k;
        static int[] a, dau;
        #endregion

        #region THủ tục
        private static void Xuat(int i)
        {
            for (int j = 1; j <= k; j++)
                Console.Write(a[j] + " ");
            Console.WriteLine();
        }

        private static void Duyet(int i)
        {
            if (i > k) Xuat(i);
            else
            {
                int j;
                for (j = a[i - 1]; j <= n; j++)
                {
                    if (dau[j] == 0)
                    {
                        a[i] = j;
                        dau[j] = 1;
                        Duyet(i+1);
                        dau[j] = 0;
                    }
                }
            }
        }
        #endregion

        static void Main(string[] args)
        {
            #region Đầu vào
            Console.Write("Nhap va n: ");
            n = Convert.ToInt32(Console.ReadLine());
            Console.Write("Nhap va k: ");
            k = Convert.ToInt32(Console.ReadLine());
            a = new int[n+1];
            dau = new int[n+1];
            for (int i = 0; i < n + 1; i++)
                dau[i] = 0;
            #endregion

            #region Xử lí
            Console.WriteLine("To hop chap " + k + " cua " + n + ": ");
            a[0] = 1;
            Duyet(1);
            #endregion

            Console.ReadKey();
        }
    }
}
Dãy cần tìm là a
Thuật toán quay lui với vòng lặp sẽ bắt đầu từ a[i-1] đề thỏa mãn điều kiện các số khác nhau và số sau lớn hơn số trước. Trong quá trình duyệt kết hợp đánh dấu phần tử đã sử dụng để không bị trùng (ở trong này mình dùng mảng dau)
Khi tìm đủ k phần tử cho mảng a thì xuất ra.

Về lí thuyết quay lui có thể tham khảo trong sách giải thuật và lập trình của Lê Minh Hoàng

Với code này chuyển thành tính chỉnh hợp cũng không có gỉ cả, chỉ cẩn thay vòng lặp thành thế này là OK
Các số trong bộ số sẽ không phải là từ a[i-1] nữa mà là từ 1

for (j = 1; j <= n; j++)
{
    if (dau[j] == 0)
    {
        a[i] = j;
        dau[j] = 1;
        Duyet(i+1);
        dau[j] = 0;
    }
}
4/13/2014
Đăng bởi :
Nhãn :

[API] Phát nhạc MP3

Như chúng ta đã biết thư viện "System.Media" chỉ cho phép chạy file âm thanh ".wav" nhiều chúng ta chạy file MP3 rất khó khăn (làm một chương trình phát nhac đơn giản chẳng hạn -- không dùng dll của Windows Media đâu nhé)

Hôm nay mình sẽ hướng dẫn các bạn sử dụng API để chạy file MP3 trong C#.
Các bước như sau :

1. Đừng quên "using System.Runtime.InteropServices;" để sử dụng API nhé.

2. Import Dll "winmm.dll"
[DllImport("winmm.dll")]

private static extern long mciSendString(string strCommand, StringBuilder strReturn, int iReturnLength, IntPtr hwndCallback);

Hàm API này không hẳn có chức năng chạy MP3 mà nó là 1 hàm cho phép thực hiện câu lệnh được Coder đưa vào qua 1 string là strCommad . như vậy parameters này là quan trọng nhất (và mình cũng không biết các param khác có chức năng gì -- thôi thì cứ null -- API thường vậy mà HIHI ^^)

3. Giới thiệu các Commad để chạy 1 file MP3
- Mở MP3 :  "open "Đường dẫn tới file mp3" type mpegvideo alias MediaFile"
ví dụ : "open "E:\MUSIC\nhac.mp3" type mpegvideo alias MediaFile"
- Chạy MP3 vừa mở :  "play MediaFile"
Có thể dùng "play MediaFile REPEAT" để phát đi phát lại file MP3 vừa mở
- Dừng MP3 : "close MediaFile"


Nếu chưa làm được hãy xem ví dụ này :

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace MP3
{
    public partial class Form1 : Form
    {
        public bool isOpen = false;

        public Form1()
        {
            InitializeComponent();
        }
                  // Import Dll này vô
        [DllImport("winmm.dll")]'

        private static extern long mciSendString(string strCommand, StringBuilder strReturn, int iReturnLength, IntPtr hwndCallback);

        // BUTTON PLAY MP3
        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog op = new OpenFileDialog();
            op.Filter = "MP3 (*.mp3)|*.mp3";
            if (op.ShowDialog() == DialogResult.OK)
            {
                string szFile = op.FileName;
                MP3Open(szFile); 
                Mp3Play(false);
            }
        }
        // BUTTON STOP MP3
        private void button2_Click(object sender, EventArgs e)
        {
            Mp3Close();
        }

        // PHẦN XỬ LÍ ----------------------------------------------------------------------------------
        public void MP3Open(string szFileName)
        {
            string szCommad = "open \"" + szFileName + "\" type mpegvideo alias MediaFile";
            MessageBox.Show(szCommad);
           mciSendString(szCommand, null, 0, IntPtr.Zero);
            isOpen = true;
        }
        public void Mp3Close()
        {
            string szCommand = "close MediaFile";
            mciSendString(szCommand, null, 0, IntPtr.Zero);
            isOpen = false;
        }

        public void Mp3Play(bool isLoop)
        {
            if (isOpen)
            {
                string szCommand = "play MediaFile";
                if (isLoop) szCommand += " REPEAT";
                mciSendString(szCommand, null, 0, IntPtr.Zero);
            }
        }
    }
}

Đăng bởi :
Nhãn : ,

[API] Kiểm tra kết nối Internet

Trong nhiều chương trình, chúng ta cần thao tác với Server qua Network , song nếu máy tính chưa kết nối Internet thì chương trình rất có thể bị "Treo" do cố gắng làm những công việc bạn code (Đơn giản như chương trình gửi mail - hãy thử ngắt kết nối Internet và chạy chương trình :D)

Hôm nay mình sẽ hướng dẫn các bạn làm sao để kiểm tra máy tính có đang kết nối Internet !

1. Nhớ "using System.Runtime.InteropServices;"  để có thể sử dụng API

2. Import DLL "wininet.dll"
[DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(out int Description, int ReservedValue);

Ở đây hàm này sẽ trả về true nếu có kết nối internet và false nếu không ^^!


* Nếu các bạn chưa làm được có thể xem ví dụ dưới đây

    public class INTERNET
    {
        [DllImport("wininet.dll")]
        private extern static bool InternetGetConnectedState(out int Description, int                                                                                                                                        ReservedValue);
        public static bool ISINTERNETCONNECTED()
        {
            int des;
            if (InternetGetConnectedState(out des, 0) == true)
                return true;
            return false;        }
   }





Đăng bởi :
Nhãn : ,

NVNhan's Blog đăng loạt bài giới thiệu và hướng dẫn từng bước xây dựng một website bằng ASP MVC


thuvienwinform - Ngôn ngữ C# ngoài lập trình cho winform còn lập trình được cho cả webform (tức các trang web). Được phát triển bởi Microsoft, hiện nay các trang web viết bằng ASP MVC ngày càng nhiều. Công nghệ MVC mang lại cho coder cách tổ chức code khoa học hơn. Hiện nay blog NVNhan đang đăng các bài viết hết sức cơ bản dành cho các bạn mới làm quen với ASP, ASPMVC có một cách tiếp cận nhanh nhất với việc lập trình web. Mời các bạn đón đọc tại:
hoặc


Giao diện NVNhan's Blog

Với tiêu chí ngắn gọn, xúc tích, đơn giản và dễ hiểu. Các bài viết trên blog sẽ trang bị cho bản các kiến thức hết sức cơn bản về lập trình web, từ lúc bắt đầu tạo project đến lúc hoàn thành ra sản phẩm.
Kính mời các bạn đón đọc!
4/10/2014
Đăng bởi :
Nhãn :

Code gửi thư bằng gmail

thuvienwinform - Ứng dụng của nó khá nhiều ví dụ như báo lỗi sản phẩm, liên hệ tác giả, lấy key,...Trong code mình dùng máy chủ smtp của google. Các bạn có thể dùng các máy chủ khác hỗ trợ smtp như OutLook nhưng khi đó địa chỉ máy chủ và cổng sẽ khác, chỉnh lại là OK. Nếu code không hoạt động thì bạn tham khảo cách cài đặt tài khoản Gmail để smtp hoạt động ở bài: http://thuvienwinform.blogspot.com/2014/03/tfs-thiet-lap-email-thong-bao-alert-cho-team-foundation-server-bang-gmail-hoac-live-mail-giup-cap-nhat-cong-viec-kip-thoi.html

Project demo: https://www.dropbox.com/s/ey7fksmiddqjpkm/thuvienwinform-GuiThu.rar (26KB)

Sử dụng 2 thư viện:
+ using System.Net.Mail;
+ using System.Net;
để thực hiện công việc này

Code:
  
private void GuiThu(string diachigui, string matkhau, string diachinhan, string tieude, string noidung)
{
//using System.Net.Mail;
//using System.Net;
    #region Tạo nội dung thư
    MailMessage mail = new MailMessage(diachigui, diachinhan, tieude, noidung);
    #endregion

    #region Cấu hình smtp
    SmtpClient smtp = new SmtpClient()
    {
        //Máy chủ smtp
        Host = "smtp.gmail.com",
        //Cổng gửi thư
        Port = 587,
        //Tài khoản Gmail
        Credentials = new NetworkCredential(diachigui, matkhau),
        EnableSsl = true
    };
    #endregion

    #region Gửi thư
    smtp.Send(mail);
    #endregion
} 
4/08/2014
Đăng bởi :
Nhãn :

[TFS]Xóa project, work Item

thuvienwinform - Thực sự thì theo phương pháp WeareHouse thì không xóa được project và Work Item trong Tfs nhưng thực tế thì ta có thể thực hiện công việc này như sau:

1. Xóa project
- Có thể Admin sẽ xóa các User khỏi project đó đi -> trên máy người khác sẽ không thấy nữa (thực tế là nó bị ẩn). Nên dùng cách này vì còn có thể khôi phục được
- Hoặc xóa trong Tfs Admin Console (không khôi phục được)

- Hoặc dùng comand sau (phải cài Visual Studio) (phải gõ vào notepad xong copy, paste vào cmd):

cd C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE
TfsDeleteProject /force /collection:http://Ohia-PC:8080/tfs/DefaultCollection/ "Xóa anh đi 2"

- Với
+ C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE:  là được dẫn đến thư mục IDE của Visual Studio
http://Ohia-PC:8080/tfs/DefaultCollection/: là đường dẫn đến Collection
+ Xóa anh đi 2 là tên project cần xóa.

2. Xóa WorkItem:
- Command:
witadmin destroywi /collection:http://Ohia-PC:8080/tfs/DefaultCollection/ /id:id1, id2, id3


- Trong đó:
http://Ohia-PC:8080/tfs/DefaultCollection/: là đường dẫn đến collection
+ id1, id2, id3: là id các workitem cần xóa

- Hoặc có thể dùng ứng dụng của TEK xóa trực tiếp ngay trong Visual Studio. Bạn nào cần liên hệ mình gửi cho :)

My dictionary - tự xây dựng từ điển cuả riêng bạn!






thuvienwinform - Cảm ơn bạn Bùi Đức Duy đã mang đến MY DICTIONARY. Một phần mềm giúp người dùng tự xây dựng 1 cuốn từ điển cho riêng mình. Phần mềm sẽ tự động thống kê và đánh giá vốn từ của bạn thông qua tổng số từ bạn đưa vào từ điển.

Link (Giải nén và sử dụng) (1.89MB) : 
https://www.mediafire.com/?qen53rkal9wx8w3

Chức năng chính : 
+ Thêm | Sửa | Xóa từ trong từ điển của bạn 1 cách dễ dàng
+ Quản lí theo tài khoản (Hỗ trợ cho nhiều người dùng 1 máy tính ... - Thống kê số từ và đánh giá)
+ Hỗ trợ đổi mật khẩu | Tên | Hình đại diện cho người dùng
+ Nâng câp lên phiên bản PRO :
--- Liên kết tài khoản trong cùng 1 máy tính (Đồng bộ hóa từ điển vào nhau)
--- Chia sẻ tài khoản sang máy tính khác

Đặc biệt phần mềm có dung lượng cực nhỏ. Chỉ ~4MB. 
Chạy trên mọi HĐH 
Hỗ trợ tốt đồ họa cho Windows 7 trở lên !



Ở trong chương trình này có 2 công nghệ khá hay là gửi thư và phát âm mình sẽ giới thiệu trong vài bài tiếp theo. Các bạn tải về và cho đánh giá nha

[TFS] Quy định về quản lí code

thuvienwinform - Có thể sau một thời gian sử dụng chúng ta sẽ gặp những lỗi gây ức chế từ việc quản lí code của TFS@! Cụ thể là hiện tượng conflict, mất file, ...Để hạn chế tình trạng này mình đề nghị như sau:

- Về lỗi thiếu file. Ta sẽ thử cho một bạn up from lên rồi một bạn get về xem có thực sự là trên server có mà lại không get được không? Nếu thực sự như vậy thì TFS quá tệ@!

- Với form của mình không được phép conflict (kể cả check-in và get last version) vì chỉ mình mình sửa form đó thôi

- Để hạn chế conflict:
+ Chỉ check-in form của mình.
+ Khi conflict ở form không phải của mình thì cứ take server version thôi.
+ Khi conflict ở form của mình thì phải xem lại ai đã check-in form đó lên vào thực hiện ghép code lại cẩn thận (Merge) rồi hẵng check-in
+ Với các file dùng chung (DB, .sln, .csproj,...) thì dành cho bạn nào làm frmMain, sau khi chỉnh lại cho các form gắn kết đc với nhau thì sẽ check-in các file này (check-in cả project - không check-in solution)  (lúc này thường là lỗi DB và thiếu Reference, còn lỗi trong form thì phải đề nghị sửa lại). Và đó sẽ là bản final cho lần sửa đó.

- Với một số form dùng chung nhau, ví dụ như dùng form hiển thị file word thì thường gặp lỗi về DB và đầu vào cho form. Để hạn chế thì phải thống nhất code đầu vào và DB trên 2 máy mới thực hiện được.

- Conflict là gì?
Conflict xẩy ra khi 2 hay nhiều người cùng sửa 1 file. Ví dụ thế này:
Người 1: lấy phiên bản 1 về -> sửa -> tải lên (Check-in) -> thành bản 2
Người 2: lấy phiên bản 1 về -> sửa -> tải lên (Check-in) -> conflict.

Khi xẩy ra conflict có 3 lựa chọn sau:
+ Merge: ghép code file của người 2 (file local) với file trên server (phiên bản 2 của người 1 up lên). Khi ghép thì ta sẽ chọn những phần nào khác nhau để lấy về. Chọn những phần khác nhau giữa 2 phiên bản sẽ có phiên bản đầy đủ của file này. Sau khi ghép xong thì có thể check-in bình thường.
+ Take Server Version: tức là sẽ lấy phiên bản trên server (phiên bản 2) về -> mất hết những gì đã sửa
+ Keep Local Version: tức là sẽ giữ nguyên bản trên máy. Không lấy bản 2 kia về. Khi này trên server là phiên bản 2. Trên máy có thể là phiên bản 3 (nhưng chưa check-in) -> rất kho cho sau này.
Phương pháp lựa chọn tối ưu vẫn là ghép code. Để hạn chế xẩy ra conflict khi check-in thì không để nhiều người cùng sửa 1 file.

Chúc chúng ta có những dự án thật thành công :)

[TFS] Chuyển Team Foundation Server giữa các server, các máy (video + ảnh)


thuvienwinform - Rất nhiều trường hợp, có thể là SQL Server gặp lỗi và phải cài lại, hay chỉ vì muốn đổi lại tên Server mà có thể xẩy ra những lỗi đối với Team Foundaiton Server (cụ thể là lỗi TF246017). Khi đó TFS sẽ mất kết nối với CSDL (cụ thể là database Tfs_Configuration). Cách khắc phục rất đơn giản. Chỉ cần vài dòng lệnh là xong!

- Chuẩn bị:
+ File TfsRestore.bat: https://www.dropbox.com/s/gclsrza6kjshtqz/TfsRestore.bat (2KB)
+ Máy có cái  Team Foundation Server, SQL Server

- Giải thich một số lệnh trong file .bat:
+ TfsConfig TfsServiceControl quiesce: dừng Team Foundation lại
+ TfsConfig TfsServiceControl unquiesce: khởi động lại Team Foundation
+ TfsConfig Accounts /ResetOwner: thiết lập tài khoản Owner cho file Database (cần thiết khi chuyển từ máy này sang máy khác)
+ TfsConfig Accounts /add /AccountType:ApplicationTier: thêm tài khoản ApplicationTier
+ TfsConfig RegisterDB: Thiết lập database cho Tfs. Đối với việc chuyển từ server này sang server khác cùng máy chỉ cẩn chuyển database và chạy lệnh này là OK

- Tình huống:
+ Thêm mới 1 server và muốn chuyển TFS sang đó
+ Hoặc chuyển TFS từ máy này sang máy khác
+ Cài lại SQL Server, cài lại win

- Cách làm này có thể khắc phục được lỗi TF246017
+ TF246017:

+ TF246017: Team Foundation Server could not connect to the database. Verify that the server that is hosting the database is operational, and that network problems are not blocking communication with the server

- Một số chú ý khi thực hiện:
+ File TfsRestore.bat phải được chạy bằng quyền Admin
+ Khi chuyển database phải stop (dừng) server đó lại. Nếu không sẽ không cho copy

- Thực hiện


Gồm có 2 bước cơ bản là:
B1: Chuyển Database
- Đầu tiên stop server đang được dùng để cài Tfs lại

- Copy các file database của Tfs (.mdf, .log) ra
+ Tìm đường dẫn
+ Thực hiện copy và paste ra đâu đó như bình thường

- Atach database sang server mới

- Tạo tài khoản mới cho database của Tfs trên server mới này
+ Chú ý với winserver thì phải yêu cầu mật khẩu bảo mật cao (hoặc bỏ tích Enfoce Password Policy)


B2: Thiết lập lại Team Foundation
Chạy file TfsRestore.bat và làm theo hướng dẫn

+ Thu Muc Tfs = Thư mục cài Team Foundation Server. Mặc định là: C:\Program Files\Microsoft Team Foundation Server 11.0\Tools
+ Server name = Tên Server mới muốn chuyển Tfs đến
+ Database name = tên database gắn kết với Tfs (mặc định là Tfs_Configuration)
+ Tai Khoan = tài khoản tạo đề quản lí Tfs_Confition ở B1

Done


Có gì vướng mắc khi chuyển Tfs các bạn có thể comment hoặc liên hệ với mình. Chúc thành công! ^^

Code một số thao tác đơn giản với xử lí hình ảnh: tăng độ sáng, độ tương phản, đổ màu,...



thuvienwinform - C# hỗ trợ chúng ta thư viện System.Drawing. Dựa vào đó chúng ta có thể thực hiện một số thao tác cơ bản với hình ảnh như thiết lập độ sáng, độ tương phản, xoay hình ảnh, hay tạo ảnh đen trắng,...Hôm nay mình xin được giới thiệu một số thao tác xử lí hình ảnh đơn giản thông qua lớp Bitmap trong System.Drawing


1. RGB
- Có thể hiểu nó là một bộ 3 số (R, G, B) nằm trong đoạn từ 0 -> 255. Mỗi số đại diện cho màu đỏ (Red - R), Xanh là cây (Green - G), Xanh lam (Blue). Bất kì màu nào cũng có thể được biểu diễn bằng bộ ba số này!
VD:
\
Màu đen: (0, 0, 0)
Màu đỏ: (255, 0, 0)
...
- Với hình ảnh (Image) nó được chia ra thành các pixel (điểm ảnh), mỗi pixel là một bộ ba số theo mô hình RGB này. Số pixcel = (chiều rộng)x(chiều cao).
- Trong C# để xử lí với các pixel này ta sử dụng lớp Bitmap trong System.Drawing (using System.Drawing)
- Cách làm chính là duyệt từng pixel và thực hiện các thao tác mong muốn trên các pixel đó để thu được bức ảnh mong muốn

2. Một số hàm, biến cơ bản
- Khai báo 1 Bitmap:
Bitmap bitmap = new Bitmap(anh);//anh là kiểu Image
Bitmap bitmap = new Bitmap(chieurong, chieucao);//chieucao, chieurong là kích thước của bitmap này
VD
Bitmap bitmap = new Bitmap(200, 200);//ảnh có kích thước 200x200

- Color:
Color c;//Bản ghi color. Khi đó bộ ba số RGB sẽ là: c.R, c.G, c.B
Color.FromArgb(r, g, b);//Lấy màu từ bộ ba số RBG
VD: màu đen
Color.FromArgb(0, 0, 0);//Màu đen
Color.Black;//Màu đen
Color.FromName("Black");//Màu đen

- Lấy màu của 1 pixel:
Color c;
c = bitmap.GetPixel(cot, hang);//cot, hang là tọa độ của pixel cần lấy màu

- Tô màu cho 1 pixel:
 bitmap.SetPixel(cot, hang, Color.FromArgb(r, g, b));//r, g, b là chỉ số RGB

câcsc
3. Thao tác cơ bản:
3.1. Chuyển ảnh về đen trắng (GrayScale):

GrayScale

- Để chuyển một ảnh về đen trắng ta chuyển  chỉ số từng pixel theo công thức: .299 * c.R + .587 * c.G + .114 * c.B

public Bitmap DenTrang(Image anh)
{
    Bitmap kq = new Bitmap(anh.Width, anh.Height);
    Bitmap anhtam = new Bitmap(anh);
    Color c;
    Byte rgb;
    for (int cot = 0; cot < anhtam.Width; cot++)
        for (int hang = 0; hang < anhtam.Height; hang++)
        {
            c = anhtam.GetPixel(cot, hang);
            rgb = (byte)(.299 * c.R + .587 * c.G + .114 * c.B);
            kq.SetPixel(cot, hang, Color.FromArgb(rgb, rgb, rgb));
        }
    return kq;
}


3.2. Chuyển ảnh về âm bản (Invert):

Invert

- Để chuyển ảnh về âm bản ta lấy 255 trừ đi từng chỉ số (làm màu từng pixel ngược lại)



public Bitmap AmBan(Image anh)
{
    Bitmap kq = new Bitmap(anh.Width, anh.Height);
    Bitmap anhtam = new Bitmap(anh);
    Color c;
    for (int cot = 0; cot < anhtam.Width; cot++)
        for (int hang = 0; hang < anhtam.Height; hang++)
        {
            c = anhtam.GetPixel(cot, hang);
            kq.SetPixel(cot, hang, Color.FromArgb(255 - c.R, 255 -  c.G, 255 -  c.B));
        }

    return kq;
}


3.4. Lọc màu (Filter):
Green Filter


- Đề lọc màu (cụ thể là theo 3 màu chính đỏ, xanh lá cây, xanh lam)
+ Màu đỏ: ta giữ nguyên màu đỏ và đảo ngược 2 màu kia (lấy 255 trù đi chỉ số G và B)
+ Tương tự với xanh và xanh lam

public Bitmap ChenMau(Image anh, int mau)
{
    //1 = do; 2 = xanh Green); 3 = xanh (blue)
    Bitmap kq = new Bitmap(anh.Width, anh.Height);
    Bitmap anhtam = new Bitmap(anh);
    Color c;
    int g = 0, r = 0 , b = 0;
    for (int cot = 0; cot < anhtam.Width; cot++)
        for (int hang = 0; hang < anhtam.Height; hang++)
        {
            c = anhtam.GetPixel(cot, hang);
            switch (mau)
            {
                case 1: r = c.R; g = c.G - 255; b = c.B - 255; break;
                case 2: r = c.R - 255; g = c.G; b = c.B - 255; break;
                case 3: r = c.R - 255; g = c.G - 255; b = c.B; break;
            }
            r = Math.Max(r, 0);
            b = Math.Max(b, 0);
            g = Math.Max(g, 0);
            kq.SetPixel(cot, hang, Color.FromArgb(r,g,b));
        }

    return kq;
}



3.5. Ghép 2 hình:
- Đề ghép 2 hình thì ta khai báo một Bitmap có chiều rộng bằng chiều rộng 1 ảnh và chiều cao bằng tổng chiều cao 2 ảnh.
- Sau đó setpixel từng pixel cho bitmap này.
Ngoài ra còn có chỉnh độ sáng (Brightness), chỉnh độ tương phản (Contrast),...các bạn có thể xem thêm
trong code.



4/06/2014
Đăng bởi :
Nhãn :

Nhận ngay 100$ cho VPS

Mua hàng ủng hộ page

Ủng hộ page

Nhãn

Code (45) Team Foundation Server (17) Database (14) News (14) product (13) toolbox (10) Linq (9) SoftDesign (8) XNA (6) API (5) Project (5) item (4)

- Bản quyền thuộc về Thư Viện WinForm - Giao diện: Metrominimalist - Thiết kế: Johanes Djogan -