MỚI NHẤT

Thứ Ba, 17 tháng 6, 2014

[WindowForm] Việt hóa giao diện GridView của DevExpress

Trong các bài trước tôi đã giới thiệu tới các bạn cách làm việc với GridView, cách fill dữ liệu, Binding với GridView - Grid Control của DevExpress. GridView trở thành 1 đối tượng khá quan trọng với các dự án quản lý danh mục, và ta chắc hẳn phải sử dụng đến nó vì công dụng cũng như sự tiện lợi của DevExpress mang lại.

DevExpress thực sự là một bộ thư viện tuyệt vời với nhiều chức năng cũng như giao diện hoàn hảo. Đối với GridView, DevExpress không chỉ cung cấp khả năng làm việc tùy biến linh động nhiều chế độ mà chúng ta còn có thể tùy biến giao diện, tùy chỉnh ngôn ngữ của từng menu item trong GridView. Sau đây tôi sẽ hướng dẫn các bạn cách Việt hóa ngôn ngữ của GridView
Việt hóa giao diện GridView của DevExpress

Trong thư mục Project add một class với nội dung như sau:
class MyGridLocalizer : GridLocalizer
{
    public override string GetLocalizedString(GridStringId id)
    {
        if (id == GridStringId.FindControlFindButton)
            return "Tìm";
        if (id == GridStringId.FindControlClearButton)
            return "Bỏ";
        if (id == GridStringId.GridGroupPanelText)
            return "Kéo thả cột vào đây để gom nhóm";
        if (id == GridStringId.MenuColumnSortAscending)
            return "Sắp xếp tăng dần";
        if (id == GridStringId.MenuColumnSortDescending)
            return "Sắp xếp giảm dần";
        if (id == GridStringId.MenuColumnClearSorting)
            return "Bỏ sắp xếp";
        if (id == GridStringId.MenuColumnGroup)
            return "Gom nhóm theo cột này";
        if (id == GridStringId.MenuGroupPanelShow)
            return "Hiện hộp gom nhóm";
        if (id == GridStringId.MenuGroupPanelHide)
            return "Ẩn hộp gom nhóm";
        if (id == GridStringId.MenuGroupPanelFullExpand)
            return "Mở tất cả các nhóm";
        if (id == GridStringId.MenuGroupPanelFullCollapse)
            return "Thu tất cả các nhóm";
        if (id == GridStringId.MenuColumnUnGroup)
            return "Bỏ gom nhóm";
        if (id == GridStringId.MenuColumnRemoveColumn)
            return "Ẩn cột này";
        if (id == GridStringId.MenuColumnShowColumn)
            return "Hiện cột này";
        if (id == GridStringId.MenuColumnColumnCustomization)
            return "Tùy chỉnh cột";
        if (id == GridStringId.CustomizationCaption)
            return "Tùy chỉnh cột";
        //if (id == GridStringId.CustomizationColumns)
        //    return "Kéo và thả cột vào đây để tùy chỉnh";
        //if (id == GridStringId.CustomizationBands)
        //    return "Kéo và thả cột vào đây để tùy chỉnh";
        //if (id == GridStringId.CustomizationFormBandHint)
        //    return "Kéo và thả cột vào đây để tùy chỉnh";
        if (id == GridStringId.CustomizationFormColumnHint)
            return "Kéo và thả cột vào đây để tùy chỉnh";
        if (id == GridStringId.MenuColumnBestFit)
            return "Căn chỉnh";
        if (id == GridStringId.MenuColumnBestFitAllColumns)
            return "Căn chỉnh tất cả";
        if (id == GridStringId.MenuColumnFilterEditor)
            return "Cài đặt lọc";
        //if (id == GridStringId.MenuColumnFilter)
        //    return "menu filter";
        if (id == GridStringId.PopupFilterCustom)
            return "(Tùy chọn)";
        if (id == GridStringId.PopupFilterAll)
            return "(Tất cả)";
        if (id == GridStringId.FilterPanelCustomizeButton)
            return "Sửa lọc";
        if (id == GridStringId.FilterBuilderCaption)
            return "Cài đặt lọc";
        if (id == GridStringId.FilterBuilderOkButton)
            return "Đồng ý";
        if (id == GridStringId.FilterBuilderApplyButton)
            return "Áp dụng";
        if (id == GridStringId.FilterBuilderCancelButton)
            return "Hủy bỏ";
        if (id == GridStringId.MenuColumnAutoFilterRowShow)
            return "Hiện hàng lọc tự động";
        if (id == GridStringId.MenuColumnAutoFilterRowHide)
            return "Ẩn hàng lọc tự động";
        if (id == GridStringId.MenuColumnFilterMode)
            return "Chế độ lọc";
        if (id == GridStringId.MenuColumnFilterModeDisplayText)
            return "Văn bản";
        if (id == GridStringId.MenuColumnFilterModeValue)
            return "Giá trị";
        if (id == GridStringId.CustomFilterDialogCancelButton)
            return "Hủy bỏ";
        //if (id == GridStringId.CustomFilterDialog2FieldCheck)
        //    return "2FieldCheck";
        if (id == GridStringId.CustomFilterDialogCaption)
            return "Hiển thị những hàng có:";
        //if (id == GridStringId.CustomFilterDialogClearFilter)
        //    return "Clear";
        if (id == GridStringId.CustomFilterDialogEmptyOperator)
            return "(Chọn phép toán)";
        if (id == GridStringId.CustomFilterDialogEmptyValue)
            return "(Điền giá trị)";
        if (id == GridStringId.CustomFilterDialogFormCaption)
            return "Tùy chọn lọc tự động";
        //if (id == GridStringId.CustomFilterDialogHint)
        //    return "fil hint";
        if (id == GridStringId.CustomFilterDialogOkButton)
            return "Đồng ý";
        if (id == GridStringId.CustomFilterDialogRadioAnd)
            return "Và";
        if (id == GridStringId.CustomFilterDialogRadioOr)
            return "Hoặc";
        return base.GetLocalizedString(id);
    }
}


Trong form chính (cần Việt hóa) ta thêm đoạn sau vào hàm khởi tạo class:
// Tùy biến giao diện Grid
GridLocalizer.Active = new MyGridLocalizer();

Lưu ý trong cả class và form đều phải:
using DevExpress.XtraGrid.Localization;

Với cách làm tương tự các bạn có thể Việt hóa các string khác của Dev.

Ví dụ: XtraMessageBox - một điều khiển khá quen thuộc các bạn có thể tham khảo tại đây

Chúc thành công.

Thứ Sáu, 13 tháng 6, 2014

[WindowForm] Làm việc với GridView - Grid Control của DevExpress

Trong bài "[LINQ] LinQ là gì và tại sao nên dùng LinQ?" tôi đã giới thiệu đến các bạn sơ qua về LINQ và Binding, trong đó có 1 thành phần quan trọng đó là GridView của DevExpress. GridView có vai trò rất quan trọng trong việc hiển thị các dữ liệu dạng bảng, danh sách trong các phần mềm quản lý danh mục... và là thành phần không thể thiếu trong Binding dữ liệu.
Ở lần trước tôi chỉ giới thiệu các bạn về cách kéo thành phần GridView tự động từ cửa sổ "Data Source" phục vụ việc Binding, trong bài này tôi sẽ hướng dẫn cách làm việc với GridView thủ công, tùy chỉnh giao diện của nó - một trong những tính năng vượt trội, thành công lớn của DevExpress.

I. Tạo và thiết lập nguồn dữ liệu cho GridView

Tạo đối tượng GridView - Grid Control

Để tạo 1 đối tượng các bạn search trong toolbox "GridControl" và kéo vào form
Làm việc với GridView - Grid Control của DevExpress

Thiết lập nguồn dữ liệu cho GridView

Bây giờ chúng ta sẽ khai báo nguồn dữ liệu (data source) cho GridView, để gridview tự động lấy các giá trị và fill vào. Đây là tiện ích lớn nhất của việc Binding: có thể tự động lấy các dữ liệu điền vào grid và liên kết với phần detail
Để chọn data source cho gridView ta click vào hình tam giác ở góc trên cùng bên phải GridView. Trong phần "Choose Data Source" ta chọn data source đã có sẵn hoặc click chọn "Add Project Data Source" nếu chưa có.
Làm việc với GridView - Grid Control của DevExpress

Khi chọn Add Project Data Source các bạn có thể chọn thêm 1 database, service, object, sharepoint nhưng bạn nên chọn object để nó có thể kết nối tới file ".dbml" đã tạo trong phần giới thiệu LINQ.
Làm việc với GridView - Grid Control của DevExpress

Sau khi chọn object ta sẽ chọn bảng/view/đối tượng làm datasource cho GridView. GridView sẽ tạo ra các cột tương tự như các trường của bảng/view/đối tượng đã chọn.
Làm việc với GridView - Grid Control của DevExpress

Bây giờ chỉ cần thêm một vài câu lệnh để set nguồn dữ liệu thực cho datasource này. Việc này đã được giới thiệu trong bài giới thiệu LINQ.

Lưu ý:

  • Data Source cho GridView không chỉ là 1 table/view thực trong database mà có thể là 1 object ảo các bạn tạo ra trong file ".dbml" hoặc 1 đối tượng của Dataset... Với những object ảo này các bạn có thể tùy chỉnh, xử lý dữ liệu cho GridView.

II. Phần giao diện của GridView

Để tùy chỉnh giao diện, dữ liệu trong các hàng/ô của GridView ta có thể xem trong cửa sổ "Properties" tương ứng của GridView hoặc đơn giản hơn có thể mở giao diện tùy chỉnh của DevExpress:
Làm việc với GridView - Grid Control của DevExpress

Trong phần "Run Designer" này các bạn có thể tùy chỉnh một số thuộc tính của header, phần hiển thị của các ô, việc sửa đổi dữ liệu trong ô, sắp xếp theo cột, thay đổi màu sắc, font chữ... và cả các kiểu hiển thị dữ liệu trong từng ô. Chẳng hạn:

1. Tùy chỉnh giao diện

Thêm/bớt, thay đổi thứ tự các cột

Làm việc với GridView - Grid Control của DevExpress

Với "gridView1" ta vẫn có các sự kiện như ở GridView thông thường như: RowClick, RowCellClick...
Làm việc với GridView - Grid Control của DevExpress


Tùy chỉnh Layout

Làm việc với GridView - Grid Control của DevExpress

Thay đổi font chữ, căn lề của header, ô trong từng cột


Ấn giữ Ctrl để chọn nhiều cột 1 lúc. Các thuộc tính trong phần AppearanceCell & AppearanceHeader như font, Col Name, Text Options, Filter, Allow Edit, Visible... 

Phân biệt hàng chẵn, lẻ

Trong tab Views, phần Appearance > EvenRow, OddRow ta có thể thay đổi một số thuộc tính như màu nền, font chữ, text options... như ở phần header:
Làm việc với GridView - Grid Control của DevExpress

Kéo xuống phần OptionsView, chọn EnableApearanceEvenRow hoặc EnableApearanceOddRow bằng true
Làm việc với GridView - Grid Control của DevExpress

2. Kiểu dữ liệu hiển thị trong ô

Mặc định khi ta chọn Data Source cho GridView thì các cột trong GridView sẽ có 1 kiểu hiển thị dữ liệu tương ứng với kiểu dữ liệu của data source. Chẳng hạn nếu ở kiểu dữ liệu data là nvarchar thì control edit dữ liệu là textEdit (của Dev)... 
Giả sử bây giờ ta có 1 cột là idNhanVien nhưng ta muốn nó hiển thị là Họ tên của Nhân viên thì phải làm thế nào??!

Bằng cách dùng bảng NhanVien để tham chiếu từng idNhanVien với HoTen tương ứng ta sẽ lấy được họ tên của nhân viên ứng với id. Chắc hẳn việc này là rất khó khăn nếu ta dùng code thông thường, không dùng Binding vì phải tương tác qua lại giữa idNhanVien và HoTen trong tất cả các công việc sau này. Khi đã có Binding + DevExpress thì việc đó trở lên tương đối easy.

Ở Run Desinger, tab Columns, với cột tương ứng ta  chỉ cần thêm 1 đối tượng "ColumnEdit" tương ứng với kiểu dữ liệu, trường thông tin muốn hiển thị. Chẳng hạn muốn hiển thị họ tên của nhân viên, vì đây là trường có sẵn (chỉ việc select), số lượng có thể rất nhiều nên ta chọn ColumnEdit là một đối tượng SearchLookupEdit (giống kiểu ComboBox nhưng có tìm kiếm của Dev). Hay như với cột ghi thông tin ghi chú (độ dài nhỏ) thì ta có thể chọn là TextEdit để sau này có thể sử dụng các thuộc tính của TextEdit như MaxLength, Mask...

Quay trở lại với bài toán của chúng ta, sau khi đã thêm đối tượng SearchLoopupEdit cho cột idNhanVien thì ta có 1 đối tượng SearchLookupEdit thông thường, có thể đặt Data Source cho nó, trường hiển thị (DisplayMember), trường giá trị tương ứng (ValueMember). Ở đây ta đặt Data Source là 1 đối tượng trong file ".dbml" tham chiếu đến bảng NhanVien, DisplayMember là HoTen, ValueMember là idNhanVien.
Làm việc với GridView - Grid Control của DevExpress

Sau khi đặt ...bindingSource.DataSource = bla bla; thì kết quả được như này
Làm việc với GridView - Grid Control của DevExpress

Như vậy đã hiển thị được họ tên nhân viên và chức vụ tương ứng mà không cần dùng quá nhiều code, trong khi đó khi cần thiết vẫn có thể lấy được các giá trị id một cách dễ dàng.

Bây giờ nảy sinh một vấn đề nữa là khi ta edit cái SearchLookUp vừa tạo ở trên nó có giao diện không đẹp lắm, đặc biệt phiền phức nếu cái bảng nhân viên có vài chục trường mà ta chỉ muốn hiển thị một vài trường như họ tên, quê quán...
Như này chẳng hạn
Làm việc với GridView - Grid Control của DevExpress

Tất nhiên các kiểu hiển thị này chỉ cần quan tâm khi ta để dữ liệu ở cột dạng AllowEdit.

Để tùy chỉnh cũng không có gì quá phức tạp, chỉ là trên cái giao diện rối rắm vì quá nhiều chức năng của DevExpress khiến ta bối rối. Trong phần Columns > cột cần thay đổi > ColumnEdit (vừa tạo ở trên) > View
Làm việc với GridView - Grid Control của DevExpress

Để đơn giản ta click vào biểu tượng dấu 3 chấm "...". Nó sẽ ra một cửa số mới để tùy chỉnh cái SearchLookupEdit này tương tự với cái tùy chỉnh GridView ta làm việc từ đầu đến giờ.
Ta cũng có thể tùy chỉnh Layout, thêm/bớt cột, đặt caption, thay đồi font chữ header, phân biệt hàng chẵn/lẻ...
Làm việc với GridView - Grid Control của DevExpress

Và kết quả cuối cùng:
Làm việc với GridView - Grid Control của DevExpress

Enjoy!!!

Chủ Nhật, 20 tháng 4, 2014

[LINQ] LinQ là gì và tại sao nên dùng LinQ?

Với SQLExpress để truy vấn dữ liệu ta phải dùng đến các câu lệnh - Query khá phức tạp. Hơn nữa để sử dụng trong ứng dụng C# lại thêm 1 tầng phức tạp nữa với các câu lệnh: dùng ConnectionString khởi tạo kết nối tới DataBase, tự khai báo các biến để chạy 1 lệnh - command, rồi còn phải tính toán đầu ra của câu lệnh... Thật là quá phức tạp nếu như ta có 1 chương trình "khủng".
Vậy làm sao để giải quyết vấn đề này? 
Một đề xuất là sử dụng Linq to SQL.
Không chỉ áp dụng cho truy vấn SQL mà LinQ còn có khả năng hỗ trợ trên nhiều nền tảng khác: XML, SQLite, Excel...

I. LinQ là gì?

LinQ là gì và tại sao nên dùng LinQ

Để giảm gánh nặng thao tác trên nhiều ngôn ngữ khác nhau và cải thiện năng suất lập trình, Microsoft đã phát triển giải pháp tích hợp dữ liệu cho .NET Framework có tên gọi là LINQ (Language Integrated Query), đây là thư viện mở rộng cho các ngôn ngữ lập trình C# và Visual Basic.NET (có thể mở rộng cho các ngôn ngữ khác) cung cấp khả năng truy vấn trực tiếp dữ liệu Object, CSDL và XML.
LINQ là một tập hợp các thành phần mở rộng cho phép viết các câu truy vấn dữ liệu ngay trong một ngôn ngữ lập trình, như C# hoặc VB.NET. Khi tạo một đối tượng LINQ thì Visual Studio sẽ tự động sinh ra các lớp có các thành phần tương ứng với CSDL của chúng ta. Khi muốn truy vấn, làm việc với CSDL ta chỉ việc gọi và truy xuất các hàm, thủ tục tương ứng của LINQ mà không cần quan tâm đến các câu lệnh SQL thông thường.
Tóm lại LINQ ra đời để giảm công sức cho những quá trình đơn giản và “chung chung” trước đây.

Điểm mạnh (chưa chắc về độ mạnh, nhưng hay) của LINQ là “viết truy vấn cho rất nhiều các đối tượng dữ liệu”. Từ CSDL, XML Data Object … thậm chí là viết truy vấn cho một biến mảng đã tạo ra trước đó. Vì vậy mới có các khái niệm LinQ to SQL, LinQ to XML, blo bla ….
Tuy nhiên so với mô hình Entity (Entity Framework), LINQ có yếu điểm là chậm và thiếu nhất quán (hiện đại tất phải hại điện).

LINQ có từ bản .NET 3.5, vậy nên tối thiểu chương trình của bạn phải chạy trên nền tảng này.
Visual Studio 2008, hoặc các phiên bản Express của nó là các bộ công cụ phát triển tiêu biểu cho ứng dụng dùng LINQ.

II. Sử dụng LinQ

LinQ là gì và tại sao nên dùng LinQ
Câu lệnh SELECT trong SQL được thực hiện bởi LINQ
Trong phần này tôi sẽ sử dụng 1 project demo để các bạn thấy được cách làm việc với LINQ như thế nào?!
CSDL là 1 bảng tbTest với 2 trường: id (kiểu int, tự động tăng - Identity) và Feild1 (kiểu nvarchar(50)).

1. Khởi tạo đối tượng LinQ to SQL

Trong project chọn Add > Data > LinQ to SQL classes

LinQ là gì và tại sao nên dùng LinQ?

Ở đây tôi tạo 1 file DB.dbml trong thư mục DB để dễ quản lý.
Sau khi có được file ta tiến hành kéo các table cần thiết vào để tự động sinh các thủ tục LinQ
LinQ là gì và tại sao nên dùng LinQ?

Vậy là xong, ta đã tạo được các thủ tục cần thiết để làm việc với LINQ. Easy??!!   :)

2. Truy vấn dữ liệu

Tương tự như Entity ta phải khai báo 1 biến DataContext để tương tác với LinQ
DB.DBDataContext db = new DB.DBDataContext();  

Có 2 kiểu truy vấn dữ liệu:
Query Syntax
var abc = from p in db.tbTests
          where p.id > 10
          select p;

// Hoặc chọn một số trường
var abc = from p in db.tbTests
          where p.id > 10
          select new
          {
              p.id,
              p.Feild1
          };
Method Syntax
var xyz = db.tbTests.Where(p => p.id > 10).Select(p => new { p.id, p.Feild1 });

Câu truy vấn SQL tương ứng
SELECT [id]
      ,[Feild1]
  FROM [dbo].[tbTest]
  WHERE [id] > 10

Chọn từ nhiều bảng theo kiểu Inner Join (lấy những bản ghi có điều kiện thỏa mãn)
// Query Syntax
var result = from p in products
             join c in categories on p.CategoryID equals c. CategoryID
             select new
             {
                 ProductName=p.ProductName,
                 CategoryName=c.CategoryName
             };

// Hoặc chọn từ 2 bảng bằng cách from 2 lần  :)
var result = from p in products
             from c in categories
             where p.ProductName equals c.CategoryName
             select new
             {
                 ProductName=p.ProductName,
                 CategoryName=c.CategoryName
             };

// Method Syntax
var result = products.Join(
             categories,
             p=>p.CategoryID,
             c=>c.CategoryID,
             (p,c) => new
             {
                 ProductName=p.ProductName,
                 CategoryName=c.CategoryName
             });

Cú pháp khác tương tự các câu lệnh trong SQL.
Các biến ở trên trả về có kiểu IEnumrable, 1 loại kiểu dữ liệu giống như List. Các thao tác cơ bản với loại biến này:

  • xyz.FirstOrDefault(): Chọn bản ghi đầu tiên hoặc mặc định
  • xyz.Skip(5): Nhảy qua n bản ghi
  • xyz.Take(5): Lấy n bản ghi đầu tiên
  • xyz.ToList(): Chuyển sang kiểu List
  • xyz.Count(): đếm số bản ghi
  • xyz.Select(...), xyz.Where(...), xyz.Join(...): Các câu lệnh truy vấn theo kiểu Method Syntax
  • bla bla

Đôi khi bạn không tìm được cú pháp thích hợp hoặc LinQ không hỗ trợ loại truy vấn mà vốn có trong SQL thì bạn có thể thực hiện trực tiếp câu lệnh đó thông qua LinQ:
var result = db.ExecuteQuery<int>("SELECT NEXT VALUE FOR seq_tbCanBo")

3. Thêm, sửa, xóa dữ liệu thông qua LinQ

Thêm dữ liệu
DB.tbTest a = new DB.tbTest();      // Khai báo đối tượng mới
a.Feild1 = txtFeild1.Text;      // id là giá trị tự động tăng > ko cần thay đổi
db.tbTests.InsertOnSubmit(a);   // Thêm đối tượng a vào
db.SubmitChanges();     // Lưu thay đổi

Sửa dữ liệu
var a = (from p in db.tbTests
         where p.id == int.Parse(txtId.Text)
         select p).FirstOrDefault();
a.Feild1 = txtFeild1.Text;
db.SubmitChanges();

Xóa dữ liệu

var a = (from p in db.tbTests
         where p.id == int.Parse(txtId.Text)
         select p).FirstOrDefault();
db.tbTests.DeleteOnSubmit(a);
db.SubmitChanges();

III. Bindding

Bindding là cách thuận tiện để thay đổi, cập nhật, thêm mới bản ghi ở CSDL một cách dễ dàng trực quan, sử dụng LinQ.
Giả sử ta thực hiện Bindding ở 1 bảng, có 2 chế độ (kiểu hiển thị) là GridView Detail:
  • Chế độ GridView: có 1 gridview để hiển thị các bản ghi trong bảng, tương tự như khi chúng ta chạy câu truy vấn SELECT * trong SQL
  • Detail: các Control cho phép thay đổi giá trị của bản ghi đang được chọn ở Gridview. Khi click vào 1 hàng ở Gridview thì dữ liệu của hàng đó sẽ được điền tự động vào các Control này.

Cách dùng Bindding:
Trong chế độ Design form, mở cửa sổ Data Sources, ở đây các bảng trong file DB.dbml (được tạo khi khởi tạo LinQ) sẽ được hiển thị, giúp ta có thể kéo vào trong form của mình
Với mỗi bảng có các tùy chọn để chọn chế độ xem: Gridview, Detail,...
LinQ là gì và tại sao nên dùng LinQ?
Tạo Bindding bằng cách kéo thả
Sau khi kéo như vậy thì nó sinh ra 1 đối tượng là tbTestBinddingSource, đây chính là đối tượng tương tác với SQL, LinQ.
Quy định nguồn dữ liệu cho Bindding:
// DataSource là 1 bảng có sẵn
tbTestBindingSource.DataSource = db.tbTests;

// Datasource là một đối tượng IEnumrable lấy từ truy vấn LINQ
tbTestBindingSource.DataSource = result;

Bạn có thể kéo 1 BinddingNavigator để thực hiện các thao tác thêm, xóa dễ dàng
LinQ là gì và tại sao nên dùng LinQ?

Khi đã có Bindding như thế này rồi thì việc thêm sửa xóa cực kỳ đơn giản, không cần code nhiều, sau khi thay đổi trên gridview, detail để lưu tất cả các thay đổi chỉ cần
tbTestBindingSource.EndEdit();
db.SubmitChanges();

Các thao tác có thể làm với BinddingSource
tbTestBindingSource.RemoveCurrent();    // Xóa hàng hiện tại

// Di chuyển trên gridview
tbTestBindingSource.MoveFirst();
tbTestBindingSource.MoveLast();
tbTestBindingSource.MoveNext();
tbTestBindingSource.MovePrevious();

tbTestBindingSource.Position = 5;   // Xác định vị trí cho Bindding

Sau số thao tác thay đổi trên grid view, bạn muốn xem số hàng thêm mới, sửa xóa??
int insert = db.GetChangeSet().Inserts.Count;
int update = db.GetChangeSet().Updates.Count;
int delete = db.GetChangeSet().Deletes.Count;


Tham khảo project demo trên tại đây.
Các bạn có thể truy cập liên kết để có thêm thông tin, các thao tác với LINQ.

Thứ Bảy, 19 tháng 4, 2014

[Windows Form] DevExpress - thư viện lập trình cho windows form với một số thủ thuật

DevExpress là 1 hệ thống thư viện lập trình cực hữu ích cho việc thiết kế, lập trình form 1 cách đơn giản, chuyên nghiệp.
DevExpress bao gồm rất nhiều Control (gần như có thể thay thế hoàn toàn các Control của .NET) và còn nhiều Control ghép, mở rộng mà .NET không có. Nó chứa từ các điều khiển cơ bản như TextEdit, Button, MessageBox, PictureBox, GridView... đến các điều khiển mở rộng, nâng cao như SearchLookupEdit, RibbonBar, SpreadSheet Control... Các điều khiển tích hợp nhiều chức năng, tùy chỉnh giúp người lập trình bớt phải code.

Điểm đặc biệt ở Dev là nó hỗ trợ nhiều Skin khác nhau, theo ý tôi thì chúng đều rất đẹp và nhìn có vẻ rất chuyên nghiệp, lập trình viên có thể để người dùng chọn Skin ngay trong khi chạy chương trình.
Vì nhiều tính năng như vậy nên bộ thư viện cũng khá là nặng và tốn thời gian khi chạy chương trình trong lần đầu load form.

Trang chủ: https://www.devexpress.com/
Download (cracked): Bản 13.1.4 (hiện nay đã có bản 13.2)

Sau đây tôi xin giới thiệu một số thủ thuật, cách sử dụng Dev hiệu quả hơn

I. Tạo form PreLoad cho form chính

Với 1 chương trình tương đối lớn, nhiều control cần load khi khởi tạo, chạy lần đầu thì việc phải đợi lâu, độ delay lớn sẽ gây cảm giác không tốt tới người dùng. Điều chúng ta có thể làm là thử tạo 1 form pre load cho main form. Tức là trong khi đang load form chính (tốn thời gian) thì ta cho hiển thị 1 form splash nhẹ hơn lên trước, sau khi form chính load xong thì form splash này mất đi. Trong form splash này có thể cho hiển thị tên phần mềm, copyright, progress bar... để người dùng không có cảm giác phải đợi lâu.

Để tạo được 1 from pre load ta làm theo các bước sau:
- Trong Project tạo 1 form DevExpress splashForm, ta sửa form này theo ý muốn ( như hình trên chẳng hạn)
- Trong form chính kéo 1 control "splashScreenManager" vào và đặt thuộc tính "ActiveSplashFormTypeInfo" cho nó là tên form splash vừa tạo ở trên. Có thể tùy chỉnh thêm 1 số tùy chọn.

II. Áp dụng, thay đổi skin cho form

Thay đổi giao diện áp dụng với form Ribbon. Có nhiều skin như Office 2013, Win 7, Mac...
Để thay đổi được cả giao diện ribbon và giao diện form phải cài đặt thuộc tính "RibbonStyle" của thành phẩn Ribbon Control là "Office2013".

Trong 1 RibbonPage > RibbonPageGroup nào đó bạn tạo 1 "RibbonGalleryBarItem", đặt tên cho nó (là rbiGallery chẳn hạn)

Trong phần code ta làm như sau:
using DevExpress.Skins;
using DevExpress.LookAndFeel;
using DevExpress.XtraBars.Ribbon;
using DevExpress.XtraBars.Ribbon.Gallery;

//
//
namespace ABC
{
    public partial class XYZ : DevExpress.XtraBars.Ribbon.RibbonForm
    {
        public XYZ()
        {
            InitializeComponent();
            // Gallery Skin
            DevExpress.XtraBars.Helpers.SkinHelper.InitSkinGallery(rbiGallery, true);
            UserLookAndFeel.Default.SetSkinStyle("Default");

Thêm nhiều skin hơn bằng cách sửa file "Program.cs", thêm đoạn sau vào:
DevExpress.UserSkins.BonusSkins.Register();
DevExpress.Skins.SkinManager.EnableFormSkins();

III. Sử dụng MessageBox của DevExpress

Việc sửa giao diện cho form đã ổn, vấn đề là những MessageBox của .NET vẫn chưa được thay đổi và không đồng bộ với giao diện của form. Vậy làm sao để khắc phục?
Dev cũng hỗ trợ cả cái MessageBox này với tên "XtraMessageBox", việc sử dụng XtraMessageBox cũng giống hệt khi ta sử dụng MessageBox. Thuận tiện hơn nữa là MessageBox này cũng thay đổi giao diện khi ta thay đổi giao diện của form.

Sử dụng XtraMessageBox như sau:
using DevExpress.XtraEditors;   // MessageBox
//
//
XtraMessageBox.Show("Có lưu file không?", "File chưa được lưu", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);

Như vậy là phần lớn các Control của form đã có thể thay đổi, tùy chỉnh với Dev.