Thứ Tư, 29 tháng 7, 2009

Composite UI Application Block (CAB) for Windows Forms

Composite UI Application Block như là một nền tảng để xây dựng các ứng dụng Windows phức tạp

Lợi ích:

- Độc lập trong việc xây dựng các module và tích hợp chúng với nhau

- Phát triển ứng dụng dựa trên yêu cầu nghiệp vụ của bài toán mà không phụ thuộc vào kiến trúc của ứng dụng

- Là một nền tảng thống nhất cho việc tích hợp các ứng dụng Windows

- Phát triển nhanh và giảm thiểu effort

Các bài toán có thể sử dụng CAB

- Online transaction processing (OLTP) front-ends, in areas such as stock distribution centers (TT phân phối chứng khoán) or data entry applications (các ứng dụng nhập liệu)

- Rich client portals to back-end services, such as portals to government services (các dịch vụ của chính phủ) or bank teller applications (các ứng dụng cho nhân viên ngân hàng)

- UI-intensive information-worker standalone applications, such as those used by call center staff (TT hỗ trợ cuộc gọi), IT support desks (TT hỗ trợ IT), or stock traders (Mua bán chứng khoán)

Kiến trúc căn bản của CAB

Cc540687.02-SCSF-CABPatterns(en-us,MSDN.10).png

CAB hỗ trợ containment model cho các components, như là services, event topics, commands, work spaces, và UI extension elements.

Container: quyết định việc hiển thị cũng như là vòng đời của các components thuộc nó

Component:

- Các components liên quan chặt chẽ với nhau trong cùng một container, từ khi được khởi tạo đến khi chúng được giải phóng.

- WorkItem là một container trong CAB

- Một component có thể truy cập tới các component khác trong cùng container

Cc540687.02-SCSF-CABPushDown(en-us,MSDN.10).png

Tích hợp giao diện trong CAB

Shell

- Ứng dụng có thể được phân chia thành nhiều phần riêng biệt, các phần này được host trong một Shell environment

- Shell Developer: xây dựng layout tổng quát cho ứng dụng để host các thành phần UI của user

- UI Elements Developer: tạo các thành components được host trên Shell.

WorkItem

- Tương tác giữa Shell và các Components thông qua WorkItem

- Mỗi ứng dụng CAB có một WorkItem gốc dùng để chứa các components được dùng chung xuyên suốt ứng dụng. Các components chung này dễ dàng được mở rộng thông qua các modules

Cc540687.02-SCSF-CABWalkthrough1(en-us,MSDN.10).png

Module

- CAB hỗ trợ customization thông sử dụng Solution Profiles trong một Catalog

- Solution Profile là danh sách các modules có thể được load trong ứng dụng khi khởi động

Cc540687.02-SCSF-CABWalkthrough2(en-us,MSDN.10).png

Views (SmartPart)

- Các modules có thể chứa phần thể hiện của dữ liệu, như các controls, form…., đó chính là các Views hoặc SmartPart

 Cc540687.02-SCSF-CABWalkthrough3(en-us,MSDN.10).png

MVC

- WorkItem đóng gói các Object Collaboration cho một use case nhất định, sử dụng Model-View-Controller (MVC) pattern

o Model. Thể hiện bởi một WorkItem state.

o View. WorkItems có thể có một hoặc nhiều views.

o Controller. Mỗi view kết hợp với các controllers để kiểm soát sự tương tác trên form của các commands, events, và subscriptions

Cc540687.02-SCSF-CABWalkthrough4(en-us,MSDN.10).png

Thứ Hai, 27 tháng 7, 2009

Convert an InfoPath 2007 form into a Word 2007 document using XSLT and C#

Tham khảo bài viết Convert an InfoPath 2007 form into a Word 2007 document using XSLT and C# để thực hiện việc Export InfoPath 2007 form data ra Word 2007. Chúng ta cần chú ý một số điểm sau:

- namespace của xsd phải có đủ trong xsl

- namespace trong w:document có đủ trong xsl:stylesheet của xsl

  • Open Microsoft Visual Studio 2005 and create a new InfoPath C# project.
  • Design an InfoPath form as shown in figure 1.

    Figure 1. InfoPath form in design mode.
  • The Main data source of the InfoPath form should resemble the following figure.

    Figure 2. Main data source of InfoPath form.
  • Create a docx file as shown in figure 3 and save it as template.docx. This Word 2007 document will be used as a template file to base your converted InfoPath forms on.

    Figure 3. The Word 2007 document to use as a template for converting InfoPath forms.
    The text ip_firstName, ip_lastName, ip_website, and table_cell_1 are used as placeholders just to make it easier later on to locate the positions in the XSLT stylesheet where to place references to the InfoPath form fields. Note that table_cell_1 is contained within a table. This table will be used to show the items from the Repeating Table on the InfoPath form.
  • Open Windows Explorer and browse to the template.docx file.
  • Copy template.docx, paste it, and rename it to template.zip.
  • Extract the files from the template.zip file.

    Figure 4. Contents of template.zip.
  • Double-click on the word folder to open it.

    Figure 5. Contents of the word folder in template.zip.
  • Open the document.xml file in Notepad and save it as transform.xsl in the same folder where template.docx is located.
  • Replace
       1: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 

    which is located at the beginning of the transform.xsl file with



       1: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
       2: <xsl:output method="xml" />
       3: <xsl:template match="/"> 

  • Append the following XSL tags to the end of the transform.xsl file:

       1: </xsl:template>
       2: </xsl:stylesheet> 

  • Switch to Microsoft Visual Studio 2005, go to the Solution Explorer, open the myschema.xsd file to view its code, copy all of the namespaces defined for the form (except for the default and xsd namespaces), and paste them as attributes of the xsl:stylesheet node in the transform.xsl file. The beginning xsl:stylesheet tag should now look something like:

       1: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
       2: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       3: xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2006-12-31T07:11:15" 
       4: xmlns:xd="http://schemas.microsoft.com/office/infopath/2003" 

  • Copy all of the namespaces defined in the w:document node in the transform.xsl file, and paste them as attributes of the xsl:stylesheet node in the transform.xsl file. The beginning xsl:stylesheet tag should now look something like:

       1: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
       2: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       3: xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2006-12-31T07:11:15" 
       4: xmlns:xd="http://schemas.microsoft.com/office/infopath/2003" xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
       5: xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006"
       6: xmlns:o="urn:schemas-microsoft-com:office:office" 
       7: xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
       8: xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"
       9: xmlns:v="urn:schemas-microsoft-com:vml"
      10: xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
      11: xmlns:w10="urn:schemas-microsoft-com:office:word"
      12: xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
      13: xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml"

  • Search for ip_firstName in the transform.xsl file and replace it with

    <xsl:value-of select="my:myFields/my:firstName" />


  • Search for ip_lastName in the transform.xsl file and replace it with

    <xsl:value-of select="my:myFields/my:lastName" />


  • Search for ip_website in the transform.xsl file and replace it with

    <xsl:value-of select="my:myFields/my:website" />


  • Search for table_cell_1 in the transform.xsl file and replace it with

    <xsl:value-of select="my:name" />


  • Search for the last </w:tblGrid> tag and append the following XSL code

    <xsl:for-each select="my:myFields/my:countries/my:country">


  • Search for the last </w:tr> tag and append the following XSL code

    </xsl:for-each>


  • The final transform.xsl file should now look something like this file.
  • Open the InfoPath form in design mode.
  • Select the Data > Data Connections... menu item.
  • Click on the Add... button on the Data Connections dialog box.
  • Select the Receive data option button and click on the Next > button.
  • Select the XML document option button and click on the Next > button.
  • Click on the Browse... button to navigate to and select the XSL file you created in step 20.
    Tip: Select All Files (*.*) in the Files of type drop-down list box to be able to see the XSLT file.
  • Click on the Next > button after you have selected the file and returned to the Data Connection Wizard dialog box.
  • Select Include the data as a resource file in the form template or template part and click on the Next > button.
  • Make sure that the Automatically retrieve data when form is opened checkbox is selected and then click on the Finish button.
  • Click on the Close button to close the Data Connections dialog box.
  • Go to the Solution Explorer window, click on the References node, and add a reference to the WindowsBase DLL that comes with the Microsoft .NET Framework 3.0.
  • Double-click on the button to open its Properties dialog box.
  • Click on the Edit Form Code... button and add the following code in the Clicked event handler that InfoPath created for you:

       1: // Define variables for the word template to use and file to create
       2: string wordTemplateFilePath = @"C:\InfoPath\ConvertToWord2007\template.docx";
       3: string wordPrintFilePath = @"C:\InfoPath\ConvertToWord2007\wordprint.docx";
       4: // Copy the template to create a new docx file
       5: File.Copy(wordTemplateFilePath, wordPrintFilePath, true);
       6: // Crack open the package
       7: Package packWordPrint = Package.Open(wordPrintFilePath, FileMode.Open, FileAccess.ReadWrite);
       8: // Retrieve the document.xml part of the new docx file
       9: PackagePart part = packWordPrint.GetPart(new Uri("/word/document.xml", UriKind.Relative));
      10: // Retrieve the xsl to use to transform the InfoPath form into document.xml
      11: DataSource ds = this.DataSources["transform"];
      12: XslCompiledTransform trans = new XslCompiledTransform();
      13: trans.Load(ds.CreateNavigator());
      14: // Create a StreamWriter to be able to write to the stream of the part
      15: using (StreamWriter partStream = new StreamWriter(part.GetStream(FileMode.Open, FileAccess.Write)))
      16: {
      17: // Transform the InfoPath form and save the XML into the stream for the part
      18: trans.Transform(this.MainDataSource.CreateNavigator(), null, partStream);
      19: // Close the stream of the part
      20: partStream.Close();
      21: }
      22: // Write changes to the package 
      23: packWordPrint.Flush();
      24: // Close the package
      25: packWordPrint.Close();
      26: // Open the new docx file in Word 2007
      27: Process proc = new Process();
      28: proc.EnableRaisingEvents = false;
      29: proc.StartInfo.FileName = "winword";
      30: proc.StartInfo.Arguments = wordPrintFilePath;
      31: proc.Start();

    NOTE: Remember to change the path to the template.docx file as required by your own situation.


  • Add the following using statements to your form's code file:

    using System.IO;
    using System.IO.Packaging;
    using System.Diagnostics;
    using System.Xml.Xsl;


  • Give your InfoPath form Full Trust by going to Tools > Form Options and selecting the Security and Trust tab. And sign your InfoPath form with a digital certificate.
  • Build your InfoPath project.
  • Export InfoPath form to Word 2003 document sử dụng XSLT và XPath

    Khi làm việc với InfoPath, nhiều khi chúng ta có nhu cầu Export ra file .doc để người dùng không phải IT pro có thể chỉnh sửa theo ý mình. Bài viết Convert an InfoPath form into a Word 2003 document and send this as an attachment in an e-mail trình bày cho các bạn cách để thực hiện điều đó. Tuy nhiên, bài viết này mới chỉ dừng lại ở việc Export giữ liệu tĩnh, nghĩa là khi chúng ta thay đổi nội dung trên form, thì khi export ra file .doc lại không thay đổi.

    Bài viết này trình bày cho các bạn một cách đầy đủ, cách để Export InfoPath form ra Word 2003 (chú ý, là Word 2003. Để export ra Word 2007 tôi sẽ trình bày trong một bài viết khác).

    1. Thiết kế một InfoPath form như sau:

    A21319952F68E79E_482_0[1]

    2. Fill form này và lưu thành file Form1.xml

    A21319952F68E79E_482_1[1]

    3. Mở file bạn vừa save từ InfoPath form (Form1.xml) trên Word. Sau đó tiến hành thêm nội dung, chỉnh sửa giao diện của file xml này trên Word.

    Sau khi format xong, chúng ta chọn File –> Save As. Trong hộp thoại Save As, chú ý là chúng ta bỏ chọn Save data only checkbox và đặt tên file là Form1_1.xml

    A21319952F68E79E_482_2[1] A21319952F68E79E_482_3[1]

    4. Việc tiếp theo là chúng ta download và cài đặt WordML Transform Inference Tool. Sau đó chúng ta sử dụng cmd để thực thi việc tạo XSLT file như sau:

    WML2XSLT.EXE "C:\InfoPath\ExportToWord2003\Form1_1.xml" -o "C:\InfoPath\ExportToWord2003\XMLToWordML.xsl"





    Chúng ta bấm Select All và click Ok nếu hộp thoại “Select namespaces” xuất hiện.


    A21319952F68E79E_482_4[1] 


    5. Quay trở lại InfoPath trong trạng thái Design mode. Chúng ta chọn File –> Save as source files


    A21319952F68E79E_482_5[1]


    6. Mở myschema.xsd trong SourceFile folder vừa export từ InfoPath, và XMLToWordML.xsl vừa mới tạo từ tool, bằng một Text editor nào đó. Sau đó chúng ta copy 2 namespace từ xsd sang xsl như sau:


    myschema.xsd

     


    <xsd:schema targetNamespace="http://schemas.microsoft.com/office/infopath/2003/myXSD/2009-07-27T07:17:59" 
    ...
    xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2009-07-27T07:17:59" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    ...
    >


    XMLToWordML.xsl sau khi copy



    <xsl:stylesheet version="1.0" 
    xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2009-07-27T07:17:59" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    ...
    >

    7. Tiếp theo chúng ta tìm đến các nội dung: “Quang” và “Nguyen Ba” được bao trong thẻ <xsl:text>….</xsl:text> của xsl, để thay thế nó bằng XPath như sau.


    <xsl:text>Quang</xsl:text> –> <xsl:value-of select="my:myFields/my:firstName" />


    <xsl:text>Nguyen Ba</xsl:text> –> <xsl:value-of select="my:myFields/my:lastName" />


    <xsl:text>http://basquang.spaces.live.com</xsl:text> –> <xsl:value-of select="my:myFields/my:website" />


    Sau đó chúng ta save file này.


    8. Quay trở lại InfoPath form ở dạng Design mode. Chúng ta chọn Tools –> Data Connections… và chọn Add button. Trong hộp thoại Data Connection Wizard chúng ta chọn “Receive Data” và trỏ tới file XMLToWordML.xsl và để mặc định các lựa chọn của Wizard. Chú ý tên cho data connection là XMLToWordML


    A21319952F68E79E_482_6[1]


    9. Vào Tools –> Options để kiểm tra Default programming language khi design form bằng InfoPath là được thiết lập cho JScript


    A21319952F68E79E_482_7[1]


    10.  Click đúp vào “Export to Word 2003” button và chọn Edit Form Code. Sau đó Add đoạn code sau trong OnClick event và Save InfoPath.


    A21319952F68E79E_482_8[1] A21319952F68E79E_482_9[1]



    var formInXML = XDocument.DOM;
    var xslXMLToWordML = XDocument.GetDOM("XMLToWordML"); 
    var formInWordML = formInXML.transformNode(xslXMLToWordML);
    var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
    xmlDoc.async = false;
    xmlDoc.loadXML(formInWordML);
    xmlDoc.save("C:\\InfoPath\\InfoPathFormInWordML.xml");
    var wordApp = new ActiveXObject("Word.Application");
    wordApp.Documents.Open("C:\\InfoPath\\InfoPathFormInWordML.xml");
    wordApp.Visible = true;

     


    11. Mở Tools –> Form Options –> Security and Trust  để chọn Full Trust và Sign this form


    A21319952F68E79E_482_10[1]







    12. Giờ chúng ta sẵn sàng sử dụng Export InfoPath to Word 2003 function


    A21319952F68E79E_482_11[1]

    Thứ Sáu, 24 tháng 7, 2009

    WPF: Binding to LINQ data

    Bài viết này trình bày cách binding to LINQ data trong WPF.

    A21319952F68E79E_435_0[1]

    Chúng ta có một class sử dụng LINQ như sau:

    namespace LINQBinding
    {
        public class Person
        {
            public string FullName { get; set; }
            public string Department { get; set; }
            public Person(string fullName, string department)
            {
                FullName = fullName;
                Department = department;
            }
        }
     
        public class People : List<Person> { }
     
        public class Hyperlogy
        {
            People people = new People         
            { 
            new Person("Duc Le", "Java"),
            new Person("Quang Nguyen", ".Net"),
            new Person("Huy Tran", "Java"),
            new Person("Nhat Mai", ".Net"),
            new Person("Nam Do", "Java"),
            };
     
            public IEnumerable<string> MicrosoftTeam
            {
                get
                {
                    return from person in people
                           where person.Department == ".Net"
                           select person.FullName;
                }
            }
        }
    }



    Chúng ta có thể binding LINQ data trong MicrosoftTeam property của class trong XAML như sau:



    Trước hết chúng ta khai báo window resource:






    <Window.Resources>    
            <local:Hyperlogy x:Key="HyperlogyCompany"></local:Hyperlogy>
    </Window.Resources>


    Sau đó binding trong listbox sử dụng MicrosoftTeam property






    <Grid DataContext="{StaticResource HyperlogyCompany}">
      <ListBox ItemsSource="{Binding Path=MicrosoftTeam}"></ListBox>
    </Grid>



    Fullcode






    <Window x:Class="LINQBinding.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="LINQ Data Binding" Height="200" Width="300" 
            xmlns:local="clr-namespace:LINQBinding">
        <Window.Resources>    
            <local:Hyperlogy x:Key="HyperlogyCompany"></local:Hyperlogy>
        </Window.Resources>
        <Grid DataContext="{StaticResource HyperlogyCompany}">
            <ListBox ItemsSource="{Binding Path=MicrosoftTeam}"></ListBox>
        </Grid>
    </Window>