Archive for 2014

Lấy IP của máy, địa chỉ IP và tên các máy trọng mạng nội bộ (LAN)

thuvienwinform - Để lấy được tên, IP, MAC của máy đang chạy hoặc các máy khác trong cùng mạng nội bộ ta sử dụng 2 thư viện System.DirectoryServices và ThuVienWinform.Mang

Tải về: https://www.dropbox.com/s/1flfyj69dt4cwxa/ThuVienWinform.Mang.rar?dl=0 (123KB)

Sử dụng:
Đầu tiền thực hiện thêm 2 thư viện này vào dự án (Add reference). Sau đó sử dụng các thuộc tính (tất cả đều trả về List<string>) trong ThuVienWinform.Mang để lấy các thông tin gồm:

ThuVienWinform.Mang.DanhSachIpCaNhan: danh sách IP của máy đang chạy
ThuVienWinform.Mang.DanhSachIpLAN: danh sách IP các máy trong mạng nội bộ
ThuVienWinform.Mang.DanhSachMAC: danh sách MAC của máy đang chạy
ThuVienWinform.Mang.DanhSachMayTrongLAN: tên các máy trong mạng nội bộ

 
MessageBox.Show("IP đầu tiên của máy là: " + ThuVienWinform.Mang.DanhSachIpCaNhan[0]);
MessageBox.Show("IP trong mạng nội bộ: " + ThuVienWinform.Mang.DanhSachIpLAN[0]);

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

Lỗi "operation is not valid due to the current state of the object"

thuvienwinform - Thật là khó chịu, mất hẳn một ngày mới khắc phục được!

- Trường hợp phát sinh lỗi:
+ Winform
+ LINQ to SQL
+ Devexpress GridControl 14.1




- Nguyên nhân: thuộc tính HasLoadedOrAssignedValue (của struct System.Data.Linq.EntityRef) luôn trả về true -> thực hiện xử lý ngoại lệ System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException() trong đoạn:

if (this._BangChuaKhoaNgoai.HasLoadedOrAssignedValue)
{
	throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
}


HasLoadedOrAssignedValue kiểm tra xem bảng chứa khóa ngoại đã có giá trị hay chưa! (chắc vậy). Oái oăm thay cái GridControl nó tự thực hiện việc này nên phải tắt nó đi!

- Khắc phục:
Chỉnh thuộc tính EnableEdit của Gridview trong GridControl về fale


Hoặc


Tham khảo thêm:




11/15/2014
Đăng bởi :

[XNA GameStudio] Bài 6 : Set Text và các hiệu ứng đối với Text


 Chào - như đã hứa hôm nay mình sẽ hướng dẫn các bạn phần còn lại của hiển thị Text.
Bài học cũng khá đơn giản nên chúng ta tiến hành luôn nhé Code rất ngắn.. nhưng mình sẽ cố gắng chú thích thật kĩ cho các bạn dễ hiểu :)

I. Set Text
- Draw() là một phương thức chạy liên tục như vòng lặp vô hạn trong game và cũng giống như Update() nên việc set Text cũng rất đơn giản như sau :

// Khai báo
string Text = "Xin chào";

// Trong phương thức Draw 
// DrawString như bài 5 đã học chỉ khác là thay cái nội dung thành biến Text thôi :D
protected override void Draw(GameTime gameTime)
{
     GraphicsDevice.Clear(Color.CornflowerBlue);
     spriteBatch.Begin();
     spriteBatch.DrawString(spriteFont, Text, new Vector2(100, 20), Color.White); 
     spriteBatch.End();

     base.Draw(gameTime);
}

// Trong phương thức Update chúng ta sẽ ôn lại cái lấy trạng thái của bàn phím nhé
protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // Lấy trạng thái bàn phím
            KeyboardState keyState = Keyboard.GetState();

            if (keyState.IsKeyDown(Keys.A))
                Text = "You pressed A key";

            base.Update(gameTime);
        }
OK hãy thử và xem thành quả nhé. Khi ấn phím A, đoạn Text sẽ được set thành "You pressed A key". Tương tự hãy làm cái Score như thế :) ... Không hiểu chỗ nào cứ comment bên dưới nhé ^^!

II. Hiệu ứng trong suốt đối với Text
Các kiểu dữ liệu trong thư viện của XNA hầu hết giống với các kiểu dữ liệu trong các thư viện C# mà chúng ta vẫn dùng, nhưng 1 số đã được thay đổi để thích ứng tốt hơn đối với lập trình game, ví dụ như gán giá trị float đôi khi không cần thêm chữ "f" đằng sau.
Và sau đây là 1 cái mình cảm thấy thú vị nhất đó là Set trong suốt đối với màu.

// Màu trắng trong suốt 50%

Color MauTrongSuot = Color.White*0.5f;
// Màu xanh trong suốt 20%
Color MauTrongSuot2 = Color.Blue*0.2f;
OK giờ các bạn có thể làm 1 đoạn chữ có hiệu ứng "sáng lên dần dần - tối đi đều đều" :)) như sau
// Khai báo
float _DoTrongSuot = 1.0f; // Khai báo biến trong suốt ban đầu là 100%

// Trong phương thức Draw cũng Draw bình thường như bài 5 nhé - chỉ sửa chỗ Color thôi
protected override void Draw(GameTime gameTime)
{
     GraphicsDevice.Clear(Color.CornflowerBlue);
     spriteBatch.Begin();
     spriteBatch.DrawString(spriteFont, Text, new Vector2(100, 20), Color.White*_DoTrongSuot); 
     spriteBatch.End();

     base.Draw(gameTime);
}

// Tới chỗ khó rồi đây... mình cần nó sáng lên tới 1 mức nào đó rồi lại tối đi
// Với Timer trong winform thì đơn giản rồi
// Nhưng vì phương thức Update() chạy liên tục nên chúng ta bắt buộc phải làm kiểu "Timer" cho nó

// Khai báo 1 biến đại diện cho thời gian
// Mục đích là tăng biến này sau mỗi lần Update() được gọi
// Tới một mức nào đó thì mới cho thực hiện lệnh (giống kiểu hẹn giờ thôi)
float _Timer = 0f;
float _GiatriCong = 0.1f;
protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // Mỗi lần Update được gọi chúng ta cộng thêm vào _Timer một giá trị tính = mini giây
           _Timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;

           if (_Timer >= 80f) // Nếu _Timer được cộng tới khi nó bằng hoặc vượt quá 80 thì mới cho chạy các lệnh của ta
           {
               // Đoạn này có tính thuật toán chắc ai học lập trình rồi cũng sẽ biết thôi, nhưng mình cũng giải thích qua qua
               // Đoạn này có nghĩa là : Cộng vào độ trong suốt thêm 1 giá trị bằng _GiatriCong
               // Nếu độ trong suốt vượt quá 1 thì phải set nó lại là 1, và _GiatriCong *= -1 có nghĩa là đổi dấu để thực hiện                                                          phép trừ (thì khi nó nó sẽ tối dần) 
               // Tương tự với giới hạn dưới là 0.2 
               _DoTrongSuot += _GiaTriCong;
               
               if (_DoTrongSuot > 1f) 
               {
                   _DongTrongSuot = 1f;
                   _GiaTriCong *= -1f;
               }   
               else if (_DoTrongSuot < 0.2f)
               {
                    _DoTrongSuot = 0.2f
                    _GiaTriCong *= -1f;
               }
               _Timer = 0f; // Reset nó
           }

            base.Update(gameTime);
        }
OK , Giờ chúng ta đã có được hiệu ứng Text như mong muốn :)

III. Các cách Draw Text khác
Phương thức DrawString trong lớp SpriteBatch cung cấp cho ta tới 6 cách DrawString và các cách mình giới thiệu từ bài 5 tới giờ đều là cách thứ 1 và cũng là cách đơn giản nhất.
Tuy nhiên chúng ta còn có 5 các khác và cũng có nhiều tác dụng hay hơn
- Có vài phương thức thay string thành StringBuilder thì cũng như nhau thôi, nên ở đâu mình không giới thiệu nữa :)

* Phương thức số 3 -- là một phương thức có nhiều chức năng nhât


spriteBatch.DrawString(SpriteFont spriteFont, string Text, Vector2 Position, Color color, float rotation, Vector2 origion, float Scale, SpriteEffects spriteEffect, float LayerDepth);

Giải thích các parameters :
- SpriteFont, Text, Position, Color mình đã giới thiệu rồi
- rotation : Đó là góc quay tính bằng Radian của text (mặc định là 0), ví dụ tôi muốn đoạn Text nó dựng ngược lên thì cho giá trị này là pi/2 (tầm 1,5x)
- origion : Tạo độ tâm của đoạn Text (Tọa độ trên màn hình sẽ được xác định theo nó) và tâm quay của Text sẽ là nó
- Scale : là độ phóng to của Text (mặc định là 1f) (là 2f thì nó to gấp 2, 0.1 thì nó to = 1/10 cái mặc định)
- SpriteEfffect : là SpriteEffect.None thì bình thường, SpriteEffects.FlipHorizontally : quay ngược theo chiều ngang (cái này phục vụ cho di chuyển nhân vật ấy, SpriteEffects.FlipVertically : quay ngược theo chiều dọc (chổng mông lên zời haha)
- float LayerDepth : cứ để là 0f đi ^^  (Vì mình chưa thấy tác dụng của nó @@)
* Tương tự ta cũng có phương thức số 4 thay float Scale thành một Vector2 Scale có nghĩa là thay vì phóng to đều 2 chiều ta sẽ có thể tùy ý phóng to theo 1 chiều mình thích

*  Bài sau sẽ là Draw ảnh và các hiệu ứng . Mong các bạn theo dõi :)
Hẹn gặp lại
7/18/2014
Đăng bởi :
Nhãn :

[XNA GameStudio] Bài 5 : Đưa một đoạn Text tiếng việt ra ngoài màn hình

Chào - Hôm nay mình sẽ hướng dẫn các bạn một bài khá đơn giản nhưng cũng rất cần thiết :)
Vì đơn giản vậy nên chúng ta vào vấn đề luôn nhé

I. Đưa một đoạn Text ra ngoài màn hình
1. Trước tiên chúng ta cần Load Font vào Content đã
- Chuột phải vào Project Content > Add > New Item như hình

- Trong cửa sổ New Item > Chọn Visual C# > SpriteFont. Cuối cùng ấn Add

>> Một File có định dạng .spritefont sẽ được tạo ra và có cấu trúc của XML file
ở đây bạn có thể chỉnh Font chữ, Size, Style....

OK giờ đến phần Code thôi.
Các bạn mở Game1.cs (mặc định là vậy) làm như sau :

Đầu tiên bạn phải khai báo một đối tượng SpriteFont đại diện cho Font mình dùng (hơi khó nói :D )
SpriteFont fontTohama;

Tiếp theo chúng ta cần Load Font này để sủ dụng
protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // Load Font
            // Phương thức Content.Load(string s) dùng để load một tài nguyên trong Project Content 
            // String s được xác định là tên file bỏ đi phần đuôi (extension) 
            fontTahoma = Content.Load("SpriteFont1");

            // TODO: use this.Content to load your game content here
        }

OK các thao tác chuẩn bị đã xong, giờ thì chỉ việc đưa dòng chữ ra ngoài màn hình Chúng ta sử dụng phương thức DrawString trong đối tượng spriteBatch
protected override void Draw(GameTime gameTime)
        {
            // Màu nền
            GraphicsDevice.Clear(Color.White);

            // Mọi thứ muốn Draw được cần gọi phương thức Begin() của đối tượng spriteBatch
            // và cuối cùng kết thúc bằng phương thức End
            spriteBatch.Begin();

            // Thư viện của XNA cung cấp cho ta 6 cách để đưa một đoạn Text ra ngoài màn hình
            // Sau đây mình dùng cách đơn giản nhất
            // DrawString(SpriteFont spriteFont, string NoiDung, Vector2 ToaDo, Color MauChu)
            spriteBatch.DrawString(fontTahoma, "Hello", new Vector2(500, 0), Color.Black);
            spriteBatch.DrawString(fontTahoma, "Draw them cai nua cho mau", new Vector2(100, 0), Color.Black);

            spriteBatch.End();

            base.Draw(gameTime);
        }
Chỉ vài thao tác như vậy chúng ta đã đưa ra màn hình một đoạn text rồi :)

 II. Sử dụng tiếng việt
XNA không hỗ trợ tiếng việt... nếu bạn cố gắng đưa một dòng tiếng việt để draw string thì ngay lập tức game bị bug.
Vậy sau đây mình sẽ hướng dẫn cách để có thể sử dụng tiếng việc trong Game (cái này có hướng dẫn trên mạng , thôi thì cứ copy về cho mọi người đỡ phải tìm :) )

- Bước 1 : Mở file .spritefont bạn đã add
- Bước 2 : Thay thế đoạn <CharacterRegion> ..... <\CharacterRegion> thành đoạn sau
<CharacterRegions>
      <CharacterRegion>
        <Start>&#32;</Start>
        <End>&#126;</End>
      </CharacterRegion>
      <CharacterRegion>
        <Start>&#192;</Start>
        <End>&#195;</End>
      </CharacterRegion>
      <CharacterRegion>
        <Start>&#200;</Start>
        <End>&#202;</End>
      </CharacterRegion>
      <CharacterRegion>
        <Start>&#204;</Start>
        <End>&#205;</End>
      </CharacterRegion>
      <CharacterRegion>
        <Start>&#210;</Start>
        <End>&#213;</End>
      </CharacterRegion>
      <CharacterRegion>
        <Start>&#217;</Start>
        <End>&#218;</End>
      </CharacterRegion>
      <CharacterRegion>
        <Start>&#221;</Start>
        <End>&#221;</End>
      </CharacterRegion>
      <CharacterRegion>
        <Start>&#224;</Start>
        <End>&#227;</End>
      </CharacterRegion>
      <CharacterRegion>
        <Start>&#232;</Start>
        <End>&#234;</End>
      </CharacterRegion>
      <CharacterRegion>
        <Start>&#236;</Start>
        <End>&#237;</End>
      </CharacterRegion>
      <CharacterRegion>
        <Start>&#242;</Start>
        <End>&#245;</End>
      </CharacterRegion>
      <CharacterRegion>
        <Start>&#249;</Start>
        <End>&#250;</End>
      </CharacterRegion>
      <CharacterRegion>
        <Start>&#253;</Start>
        <End>&#253;</End>
      </CharacterRegion>
      <CharacterRegion>
        <Start>&#258;</Start>
        <End>&#259;</End>
      </CharacterRegion>
      <CharacterRegion>
        <Start>&#272;</Start>
        <End>&#273;</End>
      </CharacterRegion>
      <CharacterRegion>
        <Start>&#296;</Start>
        <End>&#297;</End>
      </CharacterRegion>
      <CharacterRegion>
        <Start>&#360;</Start>
        <End>&#361;</End>
      </CharacterRegion>
      <CharacterRegion>
        <Start>&#416;</Start>
        <End>&#417;</End>
      </CharacterRegion>
      <CharacterRegion>
        <Start>&#431;</Start>
        <End>&#432;</End>
      </CharacterRegion>
      <CharacterRegion>
        <Start>&#7840;</Start>
        <End>&#7924;</End>
      </CharacterRegion>
      <CharacterRegion>
        <Start>&#7926;</Start>
        <End>&#7929;</End>
      </CharacterRegion>
    </CharacterRegions>
Cuối cùng Ctrl + S để Save lại
Vậy là có thể viết đươc tiếng việt ngon lành rồi :)

-- OK Hôm nay vậy thôi. hẹn gặp lại !

Bài sau mình sẽ hướng dẫn các bạn các hiệu ứng và thao tác đối với một đoạn Text 
... Coming Son


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

[XNA GameStudio] Bài 4 : Lấy trạng thái chuột & bàn phím

Chào!
Hôm nay mình sẽ hướng dẫn các bạn một thao tác đơn giản mà cực kì quan trọng trong lập trình Game đó là trạng thái chuột và bàn phím

OK, vì nó khá đơn giản nên chúng ta bắt đầu luôn nhé

I. Lấy trạng thái bàn phím
Việc này sẽ luôn được thực hiện trong thủ tục Update() vì cần thao tác trong quá trình game chạy


 protected override void Update(GameTime gameTime)
        {
            // Cho phép thoát game
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // Lấy trạng thái bàn phím
            KeyboardState keyState = Keyboard.GetState();

            // Kiểm tra có đang ấn phím Enter không
            // Trả về kiểu bool (Đúng nếu đang ấn - Sai nếu không ấn)
            if (keyState.IsKeyDown(Keys.Enter))
            {
                   // Thực hiện lệnh
            }

            // Kiểm tra có đang ở trạng thái tự do không (Không ấn)
            // Ngược với IsKeyDown
            // Trả về kiểu bool 
            if (keyState.IsKeyUp(Keys.Enter))
            {
                   // Thực hiện lệnh
            }



            // Lấy một mảng phím đang ấn
            // Trong trường hợp bạn muốn làm "Hot Key" = tổ hợp phím
            Keys[] keyPressed = keyState.GetPressedKeys();

           
            base.Update(gameTime);
        }

II. Lấy trạng thái chuột
Việc này cũng sẽ luôn được thực hiện trong thủ tục Update() vì cần thao tác trong quá trình game chạy


 protected override void Update(GameTime gameTime)
        {
            // Cho phép thoát game
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // Lấy trạng thái chuột
            MouseState mouseState = Mouse.GetState();

            // Kiểm tra xem có đang ấn chuột trái không
            // Trả về kiểu "ButtonState"
            // Tương tự với RigthButton & MiddleButton
            if (mouseState.LeftButton == ButtonState.Pressed)
            {
                    // Thực hiện
            }
            
            // Lấy giá trị của "Lăn chuột"
            // Mỗi lần lăn giá trị này được công thêm 120
            // Trả về kiểu int
            int iGiaTri = mouseState.ScrollWheelValue;

            // Lấy tọa độ chuột
            int ToaDoX = mouseState.X;
            int ToaDoY = mouseState.Y;

            base.Update(gameTime);
        }

>> Các bài đăng tiếp theo : 
  • Hiển thị dòng chữ tiếng việt trong Game
  • Đưa 1 tấm ảnh vào game
  • Di chuyển 1 tấm ảnh
  • Cách làm một trái bóng (di chuyển trái, phải , nhảy)
  • Cách làm trái bóng nảy
  • Cách đưa âm thanh, nhạc nền vào game
  • Làm nhân vật cử động được (Animation)
  • Làm game đánh bóng bàn
  • .............
OK hôm nay vậy thôi....Hẹn gặp lại !

 Xin hãy để lại Comment để làm động lực mình làm các bài tiếp theo



7/12/2014
Đăng bởi :
Nhãn :

[XNA GameStudio] Bài 3 : Tùy chỉnh cửa sổ Game | Hiển thị chuột

Hôm nay chúng ta sẽ học một bài khá đơn giản nhưng lại rất cần thiết :) ... Đó là tùy chỉnh cái cửa sổ của Game

I. Tiêu đề và kích thước

// Phương thức khởi tạo  
public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";


            // Chỉnh sửa kích thức
            graphics.PreferredBackBufferWidth = 1024;
            graphics.PreferredBackBufferHeight = 600;
            
            // Ngoài ra còn có thể để chế độ Full Screen
            // Khi đặt thuộc tính này là true thì cửa sổ game được lấp đầy màn hình + không có viền (như những game chúng ta chơi)
            graphics.IsFullScreen = true;
           
            // Chỉnh sửa tiêu đề cửa số (Tên cửa sổ của XNA không hỗ trợ tiếng việt)
            this.Window.Title = "Ten cua so";
        }

II. Hiển thị chuột


protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // Khi đặt thuộc tính này là true - chuột được hiển thị
            IsMouseVisible = true;
        }

III. Đổi màu cửa sổ


protected override void Draw(GameTime gameTime)
        {
            // Màu cửa số
            // Có thể đổi thành màu tùy thích : Color.White; Color.Blue ....
            GraphicsDevice.Clear(Color.CornflowerBlue);

            base.Draw(gameTime);
        }

OK --- Hôm nay vậy nhé --- Hẹn gặp lại !


>> Các bài đăng tiếp theo : 

  • Hiển thị dòng chữ tiếng việt trong Game
  • Đưa 1 tấm ảnh vào game
  • Di chuyển 1 tấm ảnh
  • Cách làm một trái bóng (di chuyển trái, phải , nhảy)
  • Làm game đánh bóng bàn
  • .............
Đăng bởi :
Nhãn :

[XNA GameStudio] Bài 2 : Tạo 1 Project Game - giải thích các Function mặc định

Trong những bài này mình sẽ hướng dẫn các bạn từng chi tiết nhỏ để làm một game đơn giản (Vì nếu hướng dẫn làm 1 game luôn thì có lẽ sẽ gặp khó khăn trong vấn đề trình bày ^^)

Và mình xin nhắc -- để học được XNA thì các bạn phải học C# trước nhé !

OK ... hôm nay là một vấn đề nhỏ nhưng rất nhiều người mới đã gặp khó khăn

I. Tạo Project 
- Mở VS2012 : File -> New -> Project
- Trong cửa sổ Project -> Chọn "XNA Game Studio 4.0" -> Chọn "Windows Game 4.0" như hình -> OK
- Sau đây chúng ta có Project với Solution như sau :
- Ở đây họ sẽ tạo cho chúng ta 2 Project :
+ Project thứ 1 : là Project chương trình Game
+ Project thứ 2 : chứa tài nguyên (hình ảnh, model, sprite , Font chữ ...)

II. Giải thích các thủ tục có sẵn
Ok, giờ mở Game1.cs - có sẽ có nhiều người thấy "bỡ ngỡ" trước 1 đống các thủ tục có sẵn ở đây :))
Sau đây mình sẽ giải thích từng thủ tục này.....


public Game1() 
và Initialize()     
// đều là những thứ quen thuộc đối với những người học C# nên không cân nói đến ^^

protected override void LoadContent()  // Nơi để tải các tài nguyên
protected override void Draw(GameTime gameTime) // Nơi để đưa hiển thị ra màn hình (1 tấm ảnh, 1 dòng chữ, 1 model 3D...)
protected override void Update(GameTime gameTime) // Nơi Update dữ liệu game - phương thức này chạy liên tục giống như 1 vòng lặp vô hạn


Đừng coi thường nhé..... vì trong XNA không phải bạn vứt code chỗ nào nó cũng chạy như ý đâu nhé :)

OK --- Hôm nay thế thôi -- Hẹn gặp lại !
7/11/2014
Đăng bởi :
Nhãn :

[XNA GameStudio] Bài 1 : Giới thiệu về XNA GameStudio 4.0 & Cách cài đặt - Cách Add in VS2012

I. Giới thiệu về XNA Game studio
Ở đây mình sẽ giới thiệu theo cách mình hiểu, thật đơn giản thôi (Có thì thiếu sót các pro đừng gạch đá nhé)
XNA Game Studio là một loạt các thư viện được Microsoft xây dựng nhằm hỗ trợ lập trình game, XNA khá mạnh mẽ - được tích hợp với Visual Studio và viết bằng ngôn ngữ C#. 
Nó là một công nghệ mới và phiên bản hiện tại là 4.0 tuy nhiên vẫn chưa có nhiều game "khủng" được ra lò từ XNA đơn giản vì với C++, người ta có quá nhiều Engine hỗ trợ tới tận răng việc xử lí đồ họa, các hiệu ứng vật lý ... cho hầu hết các thể loại game... Có thể kể đến : Source Engine (Các sản phẩm ra lò từ Source Engine rất nhiều như : Counter Strike - Source, Half life 2, CS:GO .... và các phiên bản tiếp theo của Counter Strike sẽ đều phát triển trên nền tảng của Source Engine) và một số Engine khác như Unreal Engine 4 (Unreal Engine hỗ trợ  việc mô phỏng không gian cực tốt) , CryEngine 3...  .. Với nhưng nền tảng như vậy thì việc viết game bằng C# trong nay mai sẽ có lẽ chưa thể phổ biến
Nhưng chúng ta ở đây có lẽ không ai đủ tiền cũng như khả năng để thực hiện 1 project sử dụng 1 trong những Engine Game trên (Engine phải mua mới có :3 ).... nên việc chọn XNA có lẽ là quyết định số 1 :D

Đây là một sản phẩm của XNA (sử dụng XNA Game Studio 3.1https://www.youtube.com/watch?v=fNMSKSwWlOo
Điều này cho thấy XNA hoàn toàn có thể tạo ra những game không thua kém các game trước đây.


II. Cách cài đặt XNA Game Studio và Add in Visual Studio 2012
1. Cài đặt XNA Game Studio 4.0
- Bước 1 : Download bản cài đặt tại : http://www.microsoft.com/en-us/download/details.aspx?id=23714 (~50MB)
- Bước 2 : Cài đặt bình thường . (Hãy chú ý xem có thành công hay không nhé -- Xem chú ý bên dưới)

Chú ý : Để có thể cài đặt thành công XNA Game Studio 4.0 máy của bạn bắt buộc phải cài đặt "Game for Windows Live" download đây

2. Tiến hành Add-in vào Visual Studio 2012
Sau khi cài đặt XNA để có thể hiện thị Project như thế này là cả một quá trình :)) 
Nó sẽ không tự động xuất hiện .... (ít nhất với VS2012)

Bây giờ chúng ta sẽ cùng thực hiện nhé. 

- Bước 1 : Đảm bảo XNA Studio 4.0 đã được cài đặt thành công
- Bước 2 : Truy cập vào đường dẫn (ở đây mình cài là mặc định - Còn nếu bạn cài vào đâu thì tương tự thế :v)
"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\Microsoft"
Copy folder "XNA Game Studio 4.0"
vào "C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\Extensions"
- Bước 3 : Mở folder "XNA Game Studio 4.0" vừa copy 
--> Mở file "extension.VSIXMANIFEST" bằng Notepad 
--> Sửa dòng " <VisualStudio Version="10.0">" thành "<VisualStudio Version="11.0">" rồi Save lại
- Bước 4 : Mở cmd và viết cmd sau : 
"C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\devenv" /setup -> Enter
Sẽ có một thông báo (dù báo lỗi hay thành công) cũng sẽ được
Bước 5 : Mở VS2012 và nhận thành quả


--- OK bài hướng dẫn hôm nay tới đây thôi. .. Hẹn gặp lại ---


---Nếu ai có nhu cầu học thì để lại nhận xét phía dưới nhé .... để mình viết tiếp---



7/10/2014
Đăng bởi :
Nhãn :

[Software][New] Phần mềm quản lí phim

thuvienwinform - Những fan của phim (như mình) thường gặp rắc rối với những chỗ để phim, có khi quên mất phim nào xem hay chưa, thể loại là gì , tên phim.... 
Hôm nay mình muốn giới thiệu phần mềm quản lí phim mình mới viết :)

Các chức năng Duyệt
- Cập nhật phim (Tất cả phim trong máy, theo ổ đĩa, theo thư mục) : quét tất cả video trong máy tính đưa vào CSDL để lưu trữ thông tin
- Tất cả phim : hiển thị tất cả phim đã lưu trong CSDL
- Theo định dạng : hiển thị phim đã lưu trong CSDL theo 1 định dạng nhất định
- Theo thể loại : hiển thị phim đã lưu trong CSDL theo 1 thể loại nhất định
- Theo trạng thái : (Đã xem/chưa xem)

Chức năng Công cụ -> Riêng tư
- Chức năng đặc biệt quan trọng đối với các bạn nam :)) ... cho phép đặt mật khẩu đối với 1 thể loại phim nào đó

Chức năng tìm kiếm
- Bạn có thể tìm kiếm phim tại đây

- Link download : https://www.mediafire.com/?iz51kr370fay8kz
(Cần Source cứ pm nhé)
- Hình ảnh











7/02/2014
Đăng bởi :
Nhãn :

Gửi dữ liệu qua mạng với ThuVienWinform.Mang.GuiDuLieuNoiBo

thuvienwinform - Hôm nay blog xin được giới thiệu thư viện truyền dữ liệu qua mạng nội bộ với những dòng lệnh đơn giản. Ứng dụng trong việc truyền tin qua mạng. Cụ thể với chương trình gửi tin nhắn (chat) chỉ cần 10 dòng lệnh là xong! Hoặc có thể xây dựng thông báo, tương tác qua mạng. Thư viện này thiết kế theo mô hình chủ - khách. Máy chủ sẽ là trạm chung chuyển dữ liệu đến các máy khách.

Thư viện: https://www.dropbox.com/s/14s4s95v3k9z1m2/ThuVienWinform.Mang.GuiDuLieuNoiBo.rar (12KB)

Chương ứng dụng mẫu: https://www.dropbox.com/s/at4os8ddwusl3w0/ThuVienWinform-GuiDuLieuNoiBo.rar (185KB)

I. GIỚI THIỆU

Ứng dụng của nó có thể tạo ra những thông báo, kiểu như thông báo của facebook vậy, mình nghĩ là rất hữu ích với những chương trình trong mạng nội bộ, khi có một ai đó thêm dữ liệu -> hiện thông báo trên các máy khác (y) (y)

1. ThuVienWinform.Mang.GuiDuLieuNoiBo
- Là lớp nền, nó như bưu điện vậy, nhận vào các phong bì từ máy khách và gửi lại nó cho các khách khác
- Gồm:
+ PhongBiLAN: (phong bì :D) lớp chứa dữ liệu truyền đi. Dữ liệu được chứa trong NoiDung (PhongBiLAN.NoiDung).

2. ThuVienWinform.Mang.GuiDuLieuNoiBo.MayChu
- Nhiệm vụ duy nhất của nó là đọc tệp cài đặt xml và tạo ra một kênh http giao tiếp với các máy khách MayChuLAN.BatDau();

3. ThuVienWinform.Mang.GuiDuLieuNoiBo.MayKhach
- Chứa lớp MayKhach, thực hiện kết nối, gửi, nhận dữ liệu với máy chủ
- Lớp MayKhach gồm:
+ Thủ tục KetNoiMayChu(): thực hiện kết nối má chủ dựa trên các cài đặt trong tệp xml
+ Thủ tục GuiDuLieu(PhongBiLAN): gửi một gói dữ liệu đến máy chủ (sau đó máy chủ xử lí và gửi đến các máy khách)
- Sự kiện NhanDuLieu: thực hiện mỗi khi thực hiện thủ tục GuiDuLieu

4. Chú ý:
Vì phương pháp truyền sự kiện qua LAN mình dùng kiểu thực hiện sự kiện trên máy chủ xong truyền kết quả về cho máy khách nên sẽ xẩy ra xung đột trong sử dụng các điều khiển (controls). Vì vậy các điều khiển được sử dụng trong sự kiện NhanDuLieu cần phải xử lí nó bằng phương thức Invoke. Cái này là tiến trình trên máy khác nên rất tiếc CheckForIntellegalCrossThreadsCall = false; không có tác dụng

II. VÍ DỤ CHƯƠNG TRÌNH GỬI TIN

Chủ:
using ThuVienWinform.Mang.GuiDuLieuNoiBo;
using ThuVienWinform.Mang.GuiDuLieuNoiBo.MayChu;

Khách:
using ThuVienWinform.Mang.GuiDuLieuNoiBo;
using ThuVienWinform.Mang.GuiDuLieuNoiBo.MayKhach;

Trong chương trình ví dụ này đối tượng được gửi đi (gói trong phong bì) là TinNhan:
[Serializable]//Đối tượng muốn gửi đi phải đánh dấu Serializable
public class TinNhan
{
    public string NguoiGui { set; get; }
    public string NoiDung { set; get; }
}

1. Khởi tạo máy chủ:
ThuVienWinform.Mang.GuiDuLieuNoiBo.MayChu.MayChuLAN.BatDau();

2. Kết nối máy khách với máy chủ:
ThuVienWinform.Mang.GuiDuLieuNoiBo.MayKhach.MayKhach khach = new ThuVienWinform.Mang.GuiDuLieuNoiBo.MayKhach.MayKhach();

khach.KetNoiMayChu();

3. Gửi tin:
PhongBiLAN phongBi = new PhongBiLAN();//Tạo ra 1 cái phong bì

phongBi.NoiDung = doiTuongCanGui;//Đưa tin nhắn vào phong bì

khach.GuiDuLieu(phongBi);//Gửi dữ liệu đi

4. Nhận tin
khach.NhanDuLieu += (phogBi) =>
    {
        MessageBox.Show(phogBi.NoiDung);
    };

6/18/2014
Đăng bởi :
Nhãn :

Chỉnh sửa thông báo DevExpress (XtraMessageBox)

thuvienwinform - Mình rất là không thích những đoạn mà xen lấn tiếng anh, tiếng việt. Điển hình là các thông báo. Mặc định các nút đề là tiếng anh(OK, Yes, No, Cancel,...) chúng ta nên việt hóa toàn bộ. Vừa dễ dàng cho người sử dụng, vừa có được giao diện đẹp.



Công việc này khá đơn giản. Tạo 1 lớp (class) là xong!
Chú ý: cần thêm DevExpress.Data; và DevExpress.XtraEditors; (Add Reference)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DevExpress.XtraEditors.Controls;
using DevExpress.Utils.Localization;

namespace ThuVienWinform.ThongBaoDevExpress
{
    //https://documentation.devexpress.com/#WindowsForms/CustomDocument1866
    public class TuyChinhDevExpress : Localizer
    {
        public string Abort { set; get; }
        public string Cancel { set; get; }
        public string Ignore { set; get; }
        public string No { set; get; }
        public string Ok { set; get; }
        public string Retry { set; get; }
        public string Yes { set; get; }

        public TuyChinhDevExpress(string abort, string cancel, string ignore, string no, string ok, string retry, string yes)
        {
            this.Abort = abort;
            this.Cancel = cancel;
            this.Ignore = ignore;
            this.No = no;
            this.Ok = ok;
            this.Retry = retry;
            this.Yes = yes;
        }

        public override string GetLocalizedString(StringId id)
        {
            if (id == StringId.XtraMessageBoxAbortButtonText) return this.Abort;
            if (id == StringId.XtraMessageBoxCancelButtonText) return this.Cancel;
            if (id == StringId.XtraMessageBoxIgnoreButtonText) return this.Ignore;
            if (id == StringId.XtraMessageBoxNoButtonText) return this.No;
            if (id == StringId.XtraMessageBoxOkButtonText) return this.Ok;
            if (id == StringId.XtraMessageBoxRetryButtonText) return this.Retry;
            if (id == StringId.XtraMessageBoxYesButtonText) return this.Yes;
            return base.GetLocalizedString(id);
        }
    }
}

Sử dụng:
Khai báo đoạn này trong sự kiện nạp (Form_load), hay trong tệp Program.cs đều được:
Chú ý: using DevExpress.XtraEditors.Controls;

Localizer.Active = new TuyChinhDevExpress("&Hủy bỏ", "&Hủy", "&Chấp nhận", "&Xác nhận", "&Được", "&Thử lại", "&Được");

Vậy là xong rồi!
6/17/2014
Đăng bởi :

Tối ưu hóa chương trình lớn gồm nhiều Form

thuvienwinform
Trích đoạn "Nếu làm theo cách này, chương trình của bạn dù  nặng đến đâu thì cũng chỉ khác nhau ở thời gian Load thôi, chứ chạy thì mượt thôi rồi :))" haha

I. Vấn đề
Những chương trình "lớn" - nhất là liên quan tới quản lí đào tạo, quản lí các loại .... đều thường dùng 20 tới 30 Form..... Hầu hết các form được gọi đi gọi lại rất nhiều trong quá trình sử dụng (nhất là những form con trong thiết kế MDI) Như vậy sẽ rất ngốn RAM ... với phương thức "this.Hide()" sẽ không giúp giải phóng bộ nhớ RAM . và bạn sẽ không thể gọi "this.Close()" để đóng hẳn form này (vì nó sẽ làm toàn bộ chương trình đóng) --> Nói chung không có phương thức nào giải phóng RAM khi các form này được gọi.

Vậy hôm nay mình sẽ hướng dẫn các bạn cách tối ưu hóa những chương trình kiểu này :)
Rất đơn giản thôi

II. Thực hiện
Ví dụ ở đây mình tạo chương trình mẫu có 6 form : frmMain, frmSplash, frm1 --> frm4

Bây giờ thay vì mỗi lần gọi phải tạo 1 đối tương như kiểu :
frmMain frm = new frmMain();
frm.Show()
Mình sẽ tận dụng form frmSplash ( 1 form load trước khi form Main hiện ra) để khởi tạo tất cả các đối tượng (mà ở đây là 5 form : frmMain, frm1--> frm4) (Không Show đâu nhé) và biến đối tượng được lưu vào 1 class có tên DTO.cs .
Ưu điểm của việc này là làm 1 cái form kiểu Loading nhìn "rất chuyên nghiệp" và các winform đã khởi tạo luôn trong trạng thái "Sẵn sàng" , gọi .Show() 1 cái là lên luôn (chứ không có tình trạng nếu form nhiều Control quá thì load lâu nữa... vì nó load sẽ rồi)

+  DTO.cs
class Winform
{
         public static frmMain MAIN;
         public static frm1 FORM1;
         public static frm2 FORM2;
         public static frm3 FORM3;
         public static frm4 FORM4;
}

+ Trong Form Splash (Load) chỉ cần khởi tạo rất đơn giản (nhớ cái form là MdiParent phải khởi tạo trước nhé)  --> Đúng nghĩa là Load nhé :))

Winform.MAIN = new frmMain();
Winform.FORM1 = new frm1();
Winform.FORM2 = new frm2();
Winform.FORM3 = new frm3();
Winform.FORM4 = new frm4();

Và từ giờ hãy tương tác với các Form theo biến static trong class Winform
Ví dụ ở form Main muốn Show frm1 chỉ cần gọi :

Winform.FORM1.Show()
Đơn giản đúng không ^^! Bây giờ nó sẽ tiết kiệm bộ nhớ đồng thời chạy nhanh hơn rất nhiều đấy :) (Vì mọi thức đều được Load trước khi dùng mà ^^!)

* Update dữ liệu
Giờ có 1 vấn đề là cần Update dữ liệu mỗi lần bật 1 form lên  (Vì form mình đã load từ khi bật chương trình - bây giờ dữ liệu có thể đã bị sửa rồi ) :D
Nếu gọi theo cách truyền thống "mỗi lần gọi lại tạo 1 đối tương mới rồi Show" thì nó tự update là đương nhiên

Nhưng theo cách này bạn sẽ làm 1 công việc khá đơn giản là viết thêm 1 phương thức Update dữ liệu nữa rồi gọi theo mỗi lần gọi phương thức Show().

Ví dụ : frm1 mình có 1 GridView, cần được làm mới mỗi khi frm1 hiện.
Trong class frm1 mình viêt:

public void CapNhatDuLieu()
{
// GetData() là 1 phương thức cập nhật lại dữ liệu
         GridView.DataSource = GetData();
}

=> Mỗi lần Show Form 1 hãy kèm thêm 1 lệnh cập nhật
Winform.FORM1.CapNhatDuLieu();
Winform.FORM1.Show();

Vậy là xong rồi.... Có vẻ hơi dài dòng nhỉ ^^!
Nếu làm theo cách này, chương trình của bạn dù  nặng đến đâu thì cũng chỉ khác nhau ở thời gian Load thôi, chứ chạy thì mượt thôi rồi :))





6/15/2014
Đăng bởi :
Nhãn :

Thêm nút lên GridView của DevExpress bằng HyperLinkEdit

thuvienwinform - Với gridView của DevExpress, nếu không nói quá thì có thể hiển thị dữ liệu với mọi cách mà ta muốn. Nó hỗ trợ quá tuyệt vời! Nhưng thêm những thứ khác ngoài dữ liệu. Cụ thể như nút,  ô lựa chọn,...ta làm thế nào! Sau đây mình xin được giới thiệu cách thêm nút lên gridView của DevExpress. Cách là là thêm một cột HyperLinkEdit cho GridView sau đó hiển thị HyperLink đó bằng hình ảnh (nhìn giống nút)



CÁC BƯỚC THỰC HIỆN (3 BƯỚC)

Bước 1: Thêm 1 cột cho GridView

Ấn mũi tên chọn Add Column

Bước 2: Chỉnh Column Edit cho cột vừa thêm. Chọn New -> HyperLinkEdit
Ấn mũi tên của cột xong sủa giá tị của Column Edit thành HyperLinkEdit

Bước 3:  Đặt ảnh cho HyperLinkEdit

Ấn mũi tên chọn Run Designer

Columns -> chọn cột vừa thêm. Chú ý tên biến ở đây là repositoryItemHyperLinkEdit1

Kéo xuống đến thuộc tính Image Chọn hình ảnh cẩn hiển thị

Căn giữa cho ảnh (mục đích là che đi chữ của cột)


Bước 4: Viết mã cho sự kiện ấn (Click) cho nó. Chúng nó sẽ viết nó trong sự kiện Form_Load:
Cách 1:
private void frmQuanLiBaiSoan_Load(object sender, EventArgs e)
{
    repositoryItemHyperLinkEdit1.Click += repositoryItemHyperLinkEdit1_Click;//Gõ += xong ấn Tab
}

private void repositoryItemHyperLinkEdit1_Click(object sender, EventArgs e)
{
    //mã sự kiện
}

Cách 2:
private void frmQuanLiBaiSoan_Load(object sender, EventArgs e)
{
    repositoryItemHyperLinkEdit1.Click += (s1, e1) =>
        {
            //mã sự kiện
        };
}

Tham khảo thêm việc tùy chình GridView tại http://nvnhan2910.blogspot.com/2014/06/windowform-lam-viec-voi-gridview-grid.html

Xem thêm:

Phân trang trong winform | Paging in winform

thuvienwinform - Phân trang thực ra là một đặc trưng trong lập trình web. Chia dữ liệu cần tải (load) ra làm nhiều phần nhỏ giúp việc hiển thị nhanh hơn (do dữ liệu tải về nhỏ hơn). Trong winform thì phân trang giúp cho sử dụng tài nguyên (cụ thể là RAM) ít hơn. Nhưng mình thử thì không giảm đi là bao :)), có lẽ do mình chưa giải phòng bộ nhớ tốt.




Sau đây mình xin giới thiệu với các bạn phân trang trong winform đằng LINQToSQL

Thư viện phân trang: https://www.dropbox.com/s/nj6fnuso2b2138p/ThuVienWinform.PhanTrang.dll (14KB)
Chương trình mẫu: https://www.dropbox.com/s/z9dvnbtceu3xv40/ThuVienWinform-PhanTrangLINQ.rar (710KB)

Nếu không tải được trên DropBox các bạn liên hệ trực tiếp thuvienwinform@gmail.com để mình gửi hoặc chạy Ultrasuft để truy cập lại DropBox

Trong chương trình mẫu có 2 tệp tin chứa cơ sở dữ liệu cho nó chạy các bạn nạp nó vào rồi sửa lại kết nối cho LINQ mới chạy được

Giới thiệu ThuVienWinform.PhanTrang:
- Với thư viện này sẽ không làm ảnh hưởng đến mã đã viết vì không cần thêm dòng code nào cả, chỉ việc khai báo và xài thui
- Khai báo:
phanTrang = new PhanTrangTruyenThong<tbPhanTrang>(this.db, this.bindingNavigator1, 20);
Hoặc
PhanTrangTuyChinh<tbPhanTrang> pTrang = new PhanTrangTuyChinh<tbPhanTrang>(this.db, button1, comboBox1, button2, bindingNavigator1.BindingSource, 20);
Trong đó:
+ tbPhanTrang là đối tượng cần phân trang, ở đây là một bảng tbPhanTrang trong CSDL
+ db là biến DataContext của LINQToSQL
+ bindingNavigator1: thanh điều hướng cho datagridView
+ 20: số hàng trên 1 trang
+ button1: là nút nhảy về trang sau
+ button2: là nút nhảy về trang trước
+ comboBox1: là comboBox để hiển thị các trang
+ bindingNagigator1.BindingSource là BindingSource của datagridView

- Chế độ:
+ PhanTrangTruyenThong: phân trang dựa vào bindingNavigator có sẵn, mình sẽ thêm 2 nút tiến lùi và 2 cái comboBox để hiển thị số trang lên đó
+ PhanTrangTuyChinh: truyền vào 2 nút và 1 comboBox có sẵn để làm 2 nút tiến lùi và hiển thị danh sách trang.

- Thuộc tính và sự kiện:
+ TrangHienTai: lấy về hoặc đặt trang hiện tại (set, get)
+ sự kiện NhayTrang: trả về hướng nhảy (tiến hoặc lùi) và số trang nhảy

- Mã phân trang bằng LINQ
 
/// <summary>
/// Lấy dữ liệu từ chiSoDau đến chiSoCuoi
/// </summary>
/// <typeparam name="doiTuongCanPhanTrang">Đối tượng cần phân trang</typeparam>
/// <param name="db">DataContext chứa dữ liệu cần phân trang</param>
/// <param name="chiSoDau">Chỉ số đầu</param>
/// <param name="chiSoCuoi">Chỉ số cuối</param>
/// <returns></returns>
public object DuLieuPhanTrang<doiTuongCanPhanTrang>(DataContext db, int chiSoDau, int chiSoCuoi) where doiTuongCanPhanTrang : class
{
    try
    {
        var phanTrangs = (from p in db.GetTable<doiTuongCanPhanTrang>()
                            select p).Skip(chiSoDau).Take(chiSoCuoi - chiSoDau);
        return phanTrangs;
    }
    catch
    {
        return null;
    }
}

- Tư tưởng phân trang theo mình hiểu như sau: có một kho dữ liệu lớn (ví dụ 10 tỷ trường), ta không tải hết 10 tỷ trường đấy về để hiển thị lên dataGridView được (cháy máy mà chết mất). Nên phải chia nhỏ ra mỗi lần hiển thị 10 nghìn cái thôi!
- Có lỗi về thư viện hoặc ý tưởng mới về phân trang cùng nhau chia sẻ các bạn nha
- Chia sẻ mã ThuVienWinform.PhanTrang.dll quan hòm thư thuvienwinform@gmail.com nha!
6/13/2014
Đăng bởi :
Nhãn : ,

Hiển thị một đối tượng lên DatagridView

thuvienwinform - Có rất nhiều trường hợp ta cần hiển thị đối tượng lên bảng để hiển thị đẹp hơn cũng như dễ dàng trong việc nhập, xử lí dữ liệu. Tương tự cách làm với LINQ thì ra chỉ cần thêm đối tượng của minh vào Data Sources rồi kéo ra dataGridview là xong (đơn giản nhất) hoặc viết mã hiển thị đối tượng đó lên bảng cũng được (nhưng công việc thiết kế như đặt tên cột, thứ tự cột, ... sẽ khó khăn hơn). Mình sẽ giới thiệu cả 2 cách

Mẫu: https://www.dropbox.com/s/9tdv0s2f5bmnxsr/thuvienwinform-HienThiDoiTuongLenDgv.rar (55KB)

Cách 1: Thêm đối tượng và Data Sources rồi kéo thả ra bảng (đơn giản nhất)
- cách này nhanh, tùy biến, thêm, xóa thuộc tính của đối tượng và thiết kế dễ  dàng (nên dùng cách này)

B1: Khai báo đối tượng:
- Đối tượng Class1 với các thuộc tính của nó

class Class1
{
    public string ThuocTinh1 { set; get; }
    public string ThuocTinh2 { set; get; }
    public string ThuocTinh3 { set; get; }
    public string ThuocTinh4 { set; get; }
    public string ThuocTinh5 { set; get; }
    public string ThuocTinh6 { set; get; }
}

B2: Thêm nó vào Data Sources 



B3: Đối tượng này ra form (phải ở chế độ thiết kế (Design))

Chọn DataGridView

Kéo ra

DataSource tự sinh

B4: thêm dữ liệu
- Chỉ cẩn thêm và data source là nó sẽ tự hiện lên bảng:

//Khai báo và truyền giá trị cho các thuộc tính của dối tượng
Class1 doiTuong = new Class1();
doiTuong.ThuocTinh1 = "1";
doiTuong.ThuocTinh2 = "2";
doiTuong.ThuocTinh3 = "3";
doiTuong.ThuocTinh4 = "4";
doiTuong.ThuocTinh5 = "5";
doiTuong.ThuocTinh6 = "6";

class1BindingSource.Add(doiTuong);//Thêm đối tượng này vào bảng

Kết quả:

- Để tùy biến giao diện ấn vào mũi tên nhỏ -> Edit Columns



Cách 2: Viết mã để hiển thị:
- Cách này khi thêm một thuộc tính cho đối tượng sẽ khó khăn trong việc sửa mã.

B1: cũng khai báo đối tượng như ở Cách 1
B2: Kéo một dataGridView ra form
B3: Viết mã nạp đối tượng lên bảng

//Dùng code
BindingSource dts = new BindingSource();//Khai báo BindingSource
dts.DataSource = typeof(Class1);// => datasource này chỉ thêm được những đối tượng Class1. Nếu không thì nó sẽ nhận typeof(đối tượng đầu tiên thêm vào)
dataGridView1.DataSource = dts;

dts.Add(doiTuong);//Thêm 1 đối tượng lên bảng (sẽ tự tạo ra 1 hàng mới). Biến doiTuong giống như ở cách 1
dts.AddNew();//Thêm 1 hàng mới (các giá trị đều rỗng)

//Đặt tên cho các cột
dataGridView1.Columns["ThuocTinh1"].HeaderText = "cột 1";
dataGridView1.Columns["ThuocTinh2"].HeaderText = "cột 2";
for (int i = 3; i <= 6; i++)
    dataGridView1.Columns["ThuocTinh" + i].HeaderText = "cột " + i;

//Sắp xếp vị trí cho cột
dataGridView1.Columns["ThuocTinh2"].DisplayIndex = 0;

Kết quả:

Lấy, sửa dữ liệu đã được thêm vào:

//Lấy dữ liệu
string dt1 = ((Class1)class1BindingSource.Current).ThuocTinh1;
string dt2 = ((Class1)class1BindingSource.Current).ThuocTinh2;

//Sửa
((Class1)class1BindingSource.Current).ThuocTinh2 = "sửa";
foreach (Class1 thuocTinh in class1BindingSource)
    thuocTinh.ThuocTinh1 = "OK";

6/03/2014
Đăng bởi :
Nhãn :

Sự kiện thay đổi nội dung tệp tin. Event change file


thuvienwinform - Chắc hẳn các bạn rất hay gặp phải thông báo này nếu dùng 2 chương trình cùng chỉnh sửa nội dung 1 tệp tin. Để bắt được sự kiện tệp tin bị thay đổi nội dung, được tạo mới hoặc bị xóa đi ta dùng FileSystemWatcher tron System.IO.

Project demo: https://www.dropbox.com/s/vv25p45gmdkat2s/thuvienwinform-FileSystemWatcher%28Kiem%20tra%20su%20thay%20doi%20cua%20file%29.rar (49KB)
 
private void KiemTraSuThayDoiCuaFile(string thuMuc, string tenFile)
{
    FileSystemWatcher fwc = new FileSystemWatcher();
    fwc.Path = thuMuc;
    fwc.Filter = tenFile;
    fwc.NotifyFilter = NotifyFilters.LastWrite;
    fwc.EnableRaisingEvents = true;
    fwc.Changed += (s1, e1) =>
    {
        //code cần thực hiện khi file thay đổi
        MessageBox.Show("File da bi thay doi");
    };
}


6/01/2014
Đăng bởi :
Nhãn :

Bắt sự kiện bật, tắt chương trình. Event start, stop process


thuvienwinform - C# hỗ trợ người lập trình biết được chương trình nào vừa được bắt đầu, chương trình nào vừa kết thúc thông qua sự kiện EventArrivedEventHandler của ManagementEventWatcher nằm trong bộ thư viện System.Management. Để bắt được các sự kiện này, đầu tiên chương trình phải có quyền admin. Để thực hiện gán quyền admin cho chương trình xem thêm tại: http://thuvienwinform.blogspot.com/2013/09/item-manifes-tchay-ung-dung-winform-voi-quyen-admin.html

Project demo: https://www.dropbox.com/s/es33d1d5413oqop/thuvienwinform-ManagermentEventWatcher%28KiemTraSuThayDoiCuaTaskMgr%29.rar

Sau khi thêm quyền admin cho chương trình, ta thoát visual ra và chạy lại nó với quyền admin
Chú ý: nếu không sử dụng được ManagementEventWatcher thì phải thực hiện Add reference System.Management bằng tay
Rồi, ok code như sau:
1. Bắt sự kiện chương trình mới được bật lên

void ChuongTrinhBat()
{
    WqlEventQuery q = new WqlEventQuery("Win32_ProcessStartTrace");
    ManagementEventWatcher w = new ManagementEventWatcher(q);
    w.EventArrived += new EventArrivedEventHandler(voidChuongTrinhBat);
    w.Start();
}

private void voidChuongTrinhTat(object sender, EventArrivedEventArgs e)
{
    string s = "";
    foreach (var pd in e.NewEvent.Properties)
        if(pd.Value != null)
            if (pd.Name == "ProcessName")// ngoai ra con co ProcessID, TIME_CREATED
                s += pd.Value.ToString() + "\n";
    MessageBox.Show("Co mot chuong trinh vua moi tat\n" + s);
}

2. Bắt sự kiện chương trình bị tắt đi

void ChuongTrinhTat()
{
    ManagementEventWatcher w1 = new ManagementEventWatcher("select ProcessName from Win32_ProcessStopTrace");
    w1.EventArrived += new EventArrivedEventHandler(voidChuongTrinhTat);
    w1.Start();
}
private void voidChuongTrinhBat(object sender, EventArrivedEventArgs e)
{
    string s = "";
    foreach (var pd in e.NewEvent.Properties)
        if (pd.Value != null)
            if (pd.Name == "ProcessName")// ngoai ra con co ProcessID, TIME_CREATED
                s += pd.Value.ToString() + "\n";
    MessageBox.Show("Co mot chuong trinh vua moi bat\n" + s);
}

- Ngoài ra có thể chỉnh lại cái đoạn select một chút để lấy những giá trị cần thiết như:
+ Lấy ProcessName: select ProcessName from Win32_ProcessStopTrace
+ Lấy thời gian: select TIME_CREATE from Win32_ProcessStartTrace
+...
5/31/2014
Đăng bởi :
Nhãn :

[CODE] Truyền dữ liệu qua lại giữa các Process và ứng dụng

thuvienwinform - Xin chào ! Hôm nay mình sẽ hướng dẫn truyền dữ liệu qua lại giữa các Process. Việc này tưởng như không quan trọng lắm nhưng thực ra nó rất cần thiết khi code các phần mềm liên quan tới quản lí máy tính như Antivirus....

I. Vấn đề
Chắc hẳn các bạn đã dùng nhiều phần mềm diệt virus và thấy luôn có 1 exe riêng cho Tray (chạy dưới khay taskbar). Hãy tự hỏi tại sao lại phải tách riêng ra như vậy mà không code gộp vào 1 exe cho dễ quản lí ???
Đơn giản thôi, vì cái Tray đó làm nhiệm vụ quản lí Runtime (thời gian thực -- chạy liên tục cùng máy tính) và nếu gộp vào thì sẽ rất ngốn RAM (Ram sẽ phải load cả phần giao diện ...) nên để hệ thống chạy "êm và không nặng nề" người ta đã làm Tray ra 1 exe riêng biệt . ^^ và bây giờ việc truyền dữ liệu giữa Process là vấn đề quan trọng

II. Giải quyết
Thời còn .NET Framework 3.0 trở xuống người ta vẫn phải truyền dữ liệu qua lại giữa Process thông qua File. Nhưng tới .NET 3.5 , đã có 1 công nghệ xuất hiện để giải quyết vấn đề này.

Hôm nay mình sẽ giới thiệu vs các bạn công nghệ Pipes - công nghệ này chạy theo mô hình Server/Client
(using System.IO.Pipes) tức là 1 process sẽ đóng vai trò như 1 máy chủ, các process khác gửi nhận dữ liệu thông qua Server.

Xem 1 ví dụ đơn giản nhé (Ví dụ vẫn là cách học dễ nhất nhỉ ^^)

* Server :
Form server của mình có 1 textbox và 1 nút
(ấn vào button sẽ gửi data trong textbox cho Client)
 
// Biến Server
private NamedPipeServerStream sv;

        public Server()
        {
            InitializeComponent(); 
        }

        private void Server_Load(object sender, EventArgs e)
        {
                   // Tạo server có tên "ServerTest"
            sv = new NamedPipeServerStream("ServerTest", PipeDirection.InOut);
                   // Đợi 1 client khác kết nối
            sv.WaitForConnection();
        }

        private void button1_Click(object sender, EventArgs e)
        {
              // Khi ấn Button1 - Gửi dữ liệu cho client (phải gửi dạng byte nhé)
            var data = Encoding.Unicode.GetBytes(this.textBox1.Text);
            sv.Write(data, 0, data.Length);
 
        }

* Client



Form Client chỉ có 1 ricktexbox để cập nhật


// Client
NamedPipeClientStream stream;

        public Client()
        {
            InitializeComponent();
            
        }

        private void Client_Load(object sender, EventArgs e)
        {
                 // Kết nối tới "ServerTest"
            stream = new NamedPipeClientStream("ServerTest");
            stream.Connect();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            // Timer này cập nhật dữ liệu liên tục dưa vào RickTextbox mình đã tạo
            var re = new byte[1000];

            stream.Read(re, 0, 1000);
            string data = Encoding.Unicode.GetString(re);

            if (data != "")
                richTextBox1.Text += "\n" + data;
        }

Chạy server trước, sau đó chạy client và thử nhé ^^!

Ô xong rồi ^^!
Vậy đã truyền được dữ liệu giữa các process ^^
5/06/2014
Đăng bởi :
Nhãn :

[Code] Xử lí sự kiện cho nhiều Control

thuvienwinform - Chào ! Khi tạo form chắc hẳn bạn sẽ gặp rất nhiều control mà sẽ dùng chung một sự kiện. Nhất là đối với các hiệu ứng cho các control (Ví dụ như sự kiện MouseMove và MouseLeave...) Hôm nay chúng ta sẽ giải quyết vấn đề này. Cũng dễ thôi ^^

 I. VẤN ĐỀ 
Đối với một Form có rất nhiều Control ... và bạn muốn Form "Lung linh" hơn thì cần thêm hiệu ứng cho các Control trong Form. Ví dụ như khi trỏ chuột vào Lable thì chữ nó đậm lên - khi ngừng trỏ thì quay lại như ban đầu. >> Bình thường bạn phải tạo từng sự kiện cho từng Lable (mỗi Lable 2 sự kiện lận đó .. điều này tương đương với 2 procedure nhỏ) Mà ví dụ như có 100 Label thì sao nhỉ --> 200 sự kiện OMG ... Đủ chết rồi đấy ^^

II. GIẢI QUYẾT 
Đơn giản thôi, ở đây chúng ta sẽ tạo ra một lớp có đầy đủ các sự kiện ... và sau đó chỉ cần truyền Control vào lớp này là xong ^^! Bắt đầu nhé : Ở đây mình sẽ tạo lớp XULIHIEUUNG như sau :
 
public class XULIHIEUUNG
    {
        Control g_Control;

        public void TAOHIEUUNG(Control c)
        {
            g_Control = c;
            btn.MouseMove += new System.Windows.Forms.MouseEventHandler(MouseMoveEvent);
            btn.MouseLeave += new System.EventHandler(MouseLeaveEvent);
        }
        public void MouseMoveEvent(object sender, EventArgs e)
        {
            g_Control.Text = "Ô bắt được con chuột";
        }
        public void MouseLeaveEvent(object sender, EventArgs e)
        {
            g_Control.Text = "Chuột chạy mất rồi";
        }
    }

Trong hàm khởi tạo form chỉ cần thêm code sau bạn chỉ cần thêm code sau đây :

 new XULIHIEUUNG().TAOHIEUUNG(button1); 

 Bây giờ thử mở Form ra coi... Khi bạn trỏ chuột vào button1 và khi di chuyển chuột ra khỏi chỗ đó .. Xem thế nào :)) (1 dòng này = 6 dòng code tay đấy, chưa kể phải mở Properties của từng Control mà chọn sự kiện)

 OK, vậy là xong rồi. Đơn giản đúng không :D
5/04/2014
Đăng bởi :
Nhãn :

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 :

Nhận ngay 100$ cho VPS

Mua hàng ủng hộ page

Ủng hộ page

Lưu trữ

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 -