Locations of visitors to this page
Onteora Software - November 2007

Onteora Software

Ken Tucker's Blog

About the author

Author Name is someone.
E-mail me Send mail

Recent posts

Recent comments

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2008

Host a WPF ListView on a Windows Form

A common question I see in the msdn forums is How do I databind a Listview control on a windows form.  Unfortunately the windows forms ListView does not support databinding.  The wpf version does support databinding and it pretty host on a windows form. Please note you need to have the .Net Framework 3.0 or greater installed for this.

 

In VS 2008 you will have a WPF Interoperability tab in the toolbox.  Drag a ElementHost on to your windows forms.  In VS 2005 you will have to add the ElementHost to the toolbox.

 

For this example I am going to bind the ListView to the list of files in My Documents.  I will be showing the name, size, and last access time.

 

So we need to create a ListView, a GridView to add to the ListView to show the columns, and 3 columns

 

Dim lstv As New System.Windows.Controls.ListView
Dim gv As New System.Windows.Controls.GridView
Dim gvcName As New System.Windows.Controls.GridViewColumn
Dim gvcSize As New System.Windows.Controls.GridViewColumn
Dim gvcLast As New System.Windows.Controls.GridViewColumn

 

For each column we have to set the header text, create a binding, and a FrameworkElementFactory to show the data . 

 

With gvcName
    .Header = "Name"
    Dim bName As New System.Windows.Data.Binding
    bName.Mode = Windows.Data.BindingMode.OneWay
    bName.Path = New System.Windows.PropertyPath("Name")
    Dim feName As New FrameworkElementFactory(GetType(System.Windows.Controls.TextBlock))
    Dim dtName As New DataTemplate
    feName.SetBinding(System.Windows.Controls.TextBlock.TextProperty, bName)
    dtName.VisualTree = feName
    .DisplayMemberBinding = bName
    .CellTemplate = dtName
End With

 

Add the column to the GridView

 

gv.Columns.Add(gvcName)

 

 

Then add the GridView to the ListView

 

lstv.View = gv

 

 

Now we can bind the ListView to a file list and add it to the ElementHost.

lstv.ItemsSource = di.GetFiles
ElementHost1.Child = lstv

 

Full Listing of code

 

Imports System.Windows.Forms.Integration
Imports System.Windows

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim di As New IO.DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments))
        Dim lstv As New System.Windows.Controls.ListView
        Dim gv As New System.Windows.Controls.GridView
        Dim gvcName As New System.Windows.Controls.GridViewColumn
        Dim gvcSize As New System.Windows.Controls.GridViewColumn
        Dim gvcLast As New System.Windows.Controls.GridViewColumn

        With gvcName
            .Header = "Name"
            Dim bName As New System.Windows.Data.Binding
            bName.Mode = Windows.Data.BindingMode.OneWay
            bName.Path = New System.Windows.PropertyPath("Name")
            Dim feName As New FrameworkElementFactory(GetType(System.Windows.Controls.TextBlock))
            Dim dtName As New DataTemplate
            feName.SetBinding(System.Windows.Controls.TextBlock.TextProperty, bName)
            dtName.VisualTree = feName
            .DisplayMemberBinding = bName
            .CellTemplate = dtName
        End With

        With gvcSize
            .Header = "Length"
            Dim bSize As New System.Windows.Data.Binding
            bSize.Mode = Windows.Data.BindingMode.OneWay
            bSize.Path = New System.Windows.PropertyPath("Length")
            Dim feSize As New FrameworkElementFactory(GetType(System.Windows.Controls.TextBlock))
            Dim dtSize As New DataTemplate
            feSize.SetBinding(System.Windows.Controls.TextBlock.TextProperty, bSize)
            dtSize.VisualTree = feSize
            .DisplayMemberBinding = bSize
            .CellTemplate = dtSize
        End With

        With gvcLast
            .Header = "Last Access"
            Dim bLast As New System.Windows.Data.Binding
            bLast.Mode = Windows.Data.BindingMode.OneWay
            bLast.Path = New System.Windows.PropertyPath("LastAccessTime")
            Dim feLast As New FrameworkElementFactory(GetType(System.Windows.Controls.TextBlock))
            Dim dtLast As New DataTemplate
            feLast.SetBinding(System.Windows.Controls.TextBlock.TextProperty, bLast)
            dtLast.VisualTree = feLast
            .DisplayMemberBinding = bLast
            .CellTemplate = dtLast
        End With
        gv.Columns.Add(gvcName)
        gv.Columns.Add(gvcSize)
        gv.Columns.Add(gvcLast)
        lstv.View = gv

        lstv.ItemsSource = di.GetFiles
        ElementHost1.Child = lstv
    End Sub
End Class


kick it on DotNetKicks.com

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: WPF | VB
Posted by Ken Tucker on Thursday, November 29, 2007 11:11 AM
Permalink | Comments (1) | Post RSSRSS comment feed

Get VS 2008 for Free

The Space Coast .Net User Group will be having VS 2008 install fest on Dec 18, 2007 @ 6:30PM

Bring your laptop to the meeting room at Charlie and Jakes and the great Joe Healy will allow you to install a copy of Visual Studio 2008 professional for free.  While Visual Studio 2008 is installing buy yourself something to eat or drink and have some fun.


** Visual Studio 2008 must be installed at the meeting **
**  Pease uninstall any Orcas or VS 2008 betas before the meeting **

 

There are a limited number of copies of VS 2008 available

 

Register if You plan to attend

 

Don't live in Brevard County Florida but still want a free copy of VS 2008 pro check out Tim Heuer's Blog to see if there is a install fest near you.

 http://timheuer.com/blog/archive/2007/11/27/get-visual-studio-2008-professional-for-free-installfest.aspx

 


kick it on DotNetKicks.com

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: VS 2008 | User Group
Posted by Ken Tucker on Wednesday, November 28, 2007 8:19 PM
Permalink | Comments (1) | Post RSSRSS comment feed

Change the Framework Version of a Project in VS 2008

Visual Studio 2008 allows you to switch which version of the .net framework your project targets.  The available options are 2.0, 3.0, and 3.5. 

To change the framework version open up your project properties compile tab

 

 

You will find the framework option combobox on the form that opens when you press the Advanced Compile Options button

 

 

 

Visual studio will save the project, close, and finally restart with project opened up when you change the framwork version for your project


kick it on DotNetKicks.com

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: VB | VS 2008
Posted by Ken Tucker on Monday, November 26, 2007 10:52 AM
Permalink | Comments (4) | Post RSSRSS comment feed

Using Linq to XML to create an excel spreadsheet

For this example we are going to create a Excel 2007 spreadsheet using the Microsoft OpenXml Sdk and Linq to XML.

To start with lets create a new Windows forms app which targets the .Net Framework 3.5.  Add a Linq to Sql design surface to your project and name it Northwind and drag the Northwind Products table on to the surface.  On the windows form I added a DataGridview to display the data we are going to export to excel.  We also need a button named btnExport on the form.

To create a excel spreadsheet we need to use the openxml sdk to create a spreadsheet document, workbook, worksheet, and a string table. 

       Using doc = SpreadsheetDocument.Create("Export.xlsx", SpreadsheetDocumentType.Workbook)
            Dim workbook = doc.AddWorkbookPart
            Dim stringTable = workbook.AddNewPart(Of SharedStringTablePart)()
            Dim worksheet = workbook.AddNewPart(Of WorksheetPart)()

The worksheet, workbook, and string table are xml documents contained inside a package.  Before we get to far we need to import a few xml namespaces

 

Imports <xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
Imports <xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">

 

Now that we imported the name space we can use some of the new xml features in VB 2008 to create the xml documents.  Since we are not using a string table we just need a blank xml file

 

Dim xmlStringTable = <sst></sst>

The workbook xml needs to relate the spreadsheet with its id

 

           Dim xmlWorkbook = <workbook>
                                  <sheets>
                                      <sheet name="Exported" sheetId="1" r:id=<%= sheetId %>></sheet>
                                  </sheets>
                              </workbook>


Note the <%= sheetId %> allows you to get data from a variable

 

Finally we need to create the worksheet.  In the worksheet we set the column widths and use a linq query to populate the data.

            Dim xmlWorkSheet = <worksheet>
                                   <sheetFormatPr defaultRowHeight="15"/>
                                   <cols>
                                       <col min="1" max="1" width="30" bestFit="1" customWidth="1"/>
                                       <col min="2" max="2" width="10" bestFit="1" customWidth="1"/>
                                   </cols>
                                   <sheetData>
                                       <row>
                                           <c t="inlineStr">
                                               <is>
                                                   <t>Product Name</t>
                                               </is>
                                           </c>
                                           <c t="inlineStr">
                                               <is>
                                                   <t>Unit Price</t>
                                               </is>
                                           </c>
                                       </row>
                                       <%= From p In db.Products Select _
                                           <row>
                                               <c t="inlineStr">
                                                   <is>
                                                       <t><%= p.ProductName %></t>
                                                   </is>
                                               </c>
                                               <c>
                                                   <v><%= p.UnitPrice %></v>
                                               </c>
                                           </row> %>
                                   </sheetData>
                               </worksheet>

 

Here is the function for writing the xml to the file

   Sub WriteXmlToPart(ByVal part As OpenXmlPart, ByVal x As XElement)
        Dim fs As New IO.StreamWriter(part.GetStream, New System.Text.UTF8Encoding)

        Dim xmlWriter As New Xml.XmlTextWriter(part.GetStream, New UTF8Encoding)
        xmlWriter.Formatting = Xml.Formatting.Indented
        Dim enc As New UTF8Encoding

        xmlWriter.WriteStartDocument()
        x.WriteTo(xmlWriter)
        xmlWriter.WriteEndDocument()
        xmlWriter.Flush()
        xmlWriter.Close()
    End Sub

 

Here is the complete listing for program

 

Imports Microsoft.Office.DocumentFormat.OpenXml.Packaging
Imports System.Text
Imports <xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
Imports <xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">

Public Class Form1
    Dim bs As New BindingSource
    Dim db As New NorthwindDataContext

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        bs.DataSource = From p In db.Products _
                        Select p.ProductName, p.UnitPrice

        DataGridView1.DataSource = bs
    End Sub

    Private Sub btnExport_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExport.Click
        Using doc = SpreadsheetDocument.Create("Export.xlsx", SpreadsheetDocumentType.Workbook)
            Dim workbook = doc.AddWorkbookPart
            Dim stringTable = workbook.AddNewPart(Of SharedStringTablePart)()
            Dim worksheet = workbook.AddNewPart(Of WorksheetPart)()
            Dim sheetId = workbook.GetIdOfPart(worksheet)

            'create the string table
            Dim xmlStringTable = <sst></sst>
            WriteXmlToPart(stringTable, xmlStringTable)

            'create the workbook
            Dim xmlWorkbook = <workbook>
                                  <sheets>
                                      <sheet name="Exported" sheetId="1" r:id=<%= sheetId %>></sheet>
                                  </sheets>
                              </workbook>
            WriteXmlToPart(workbook, xmlWorkbook)

            'create the spreadsheet
            Dim xmlWorkSheet = <worksheet>
                                   <sheetFormatPr defaultRowHeight="15"/>
                                   <cols>
                                       <col min="1" max="1" width="30" bestFit="1" customWidth="1"/>
                                       <col min="2" max="2" width="10" bestFit="1" customWidth="1"/>
                                   </cols>
                                   <sheetData>
                                       <row>
                                           <c t="inlineStr">
                                               <is>
                                                   <t>Product Name</t>
                                               </is>
                                           </c>
                                           <c t="inlineStr">
                                               <is>
                                                   <t>Unit Price</t>
                                               </is>
                                           </c>
                                       </row>
                                       <%= From p In db.Products Select _
                                           <row>
                                               <c t="inlineStr">
                                                   <is>
                                                       <t><%= p.ProductName %></t>
                                                   </is>
                                               </c>
                                               <c>
                                                   <v><%= p.UnitPrice %></v>
                                               </c>
                                           </row> %>
                                   </sheetData>
                               </worksheet>

            WriteXmlToPart(worksheet, xmlWorkSheet)

        End Using
    End Sub

    Sub WriteXmlToPart(ByVal part As OpenXmlPart, ByVal x As XElement)
        Dim fs As New IO.StreamWriter(part.GetStream, New System.Text.UTF8Encoding)

        Dim xmlWriter As New Xml.XmlTextWriter(part.GetStream, New UTF8Encoding)
        xmlWriter.Formatting = Xml.Formatting.Indented
        Dim enc As New UTF8Encoding

        xmlWriter.WriteStartDocument()
        x.WriteTo(xmlWriter)
        xmlWriter.WriteEndDocument()
        xmlWriter.Flush()
        xmlWriter.Close()
    End Sub

End Class


kick it on DotNetKicks.com

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: Linq | xml | open xml
Posted by Ken Tucker on Sunday, November 25, 2007 4:30 AM
Permalink | Comments (1) | Post RSSRSS comment feed

Linq to DataSet

Linq allows you to query the data in a dataset.  For this example I load the Products and Categories table from the Northwind Database.  I then do a join query to export the Product Name, Unit Price, and Category Name into a list which I display in a datagridview.  Note a query of this type will not display in a datagridview you need to set the datasource equal to the query's Tolist method.

Imports System.Data.SqlClient

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim strConn As String = _
                "Server = .\SQLEXPRESS;Database = NorthWind; Integrated Security = SSPI;"
        Dim conn As New SqlConnection(strConn)
        Dim da As New SqlDataAdapter("Select * from Products; Select * from Categories", conn)
        Dim ds As New DataSet
        da.Fill(ds)
        Debug.Print(ds.Tables(1).TableName)
        Dim products As DataTable = ds.Tables(0)
        Dim categories As DataTable = ds.Tables(1)
        Dim query = From p In products.AsEnumerable _
                    Join c In categories.AsEnumerable _
                    On p.Field(Of Int32)("CategoryID") Equals c.Field(Of Int32)("CategoryID") _
                    Select New With {.ProductName = p.Field(Of String)("ProductName"), _
                                    .Price = p.Field(Of Decimal)("UnitPrice"), _
                                    .Category = c.Field(Of String)("CategoryName")}

        DataGridView1.DataSource = query.ToList
    End Sub
End Class

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: Linq | VB | VS 2008
Posted by Ken Tucker on Thursday, November 08, 2007 11:05 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Paging a Windows Forms DataGridView with LINQ

Since Visual Studio 2008 is due out by the end of the Month I am updating some of my datagridview samples for LINQ.

To start off create a new windows forms application in VS 2008 make sure you select FrameWork 3.5 so you can use linq

 

 

 

I now added a new Linq to Sql designer to the project and named it Northwind.  Drag the Northwind Products Table on to the design surface from the Server Explorer.

 

 

 

 

 

On your windows forms add a DataGridView (DataGridView1) and a NumericUpDown control (nuPage).  For this example I will have the datagridview show 15 items at a time.  In the form load event we will figure out how many pages there are and load the first 15 items into the datagridview.  In the NumericUpdown controls value changed event we will update the data displayed

 

Public Class Form1
    Dim bs As New BindingSource

    Private intPages As Integer
    Dim db As New NorthwindDataContext

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        intPages = Math.Ceiling(db.Products.Count / 15)
        nuPage.Maximum = intPages
        nuPage.Minimum = 1
        Dim p = From prod In db.Products _
                Select prod Skip 0 Take 15
        bs.DataSource = p
        bs.AllowNew = False
        DataGridView1.DataSource = bs
    End Sub


    Private Sub nuPage_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles nuPage.ValueChanged
        Dim p = From prod In db.Products _
                Select prod Skip (nuPage.Value - 1) * 15 Take 15
        bs.DataSource = p
    End Sub
End Class

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: DataGridView | Linq | VS 2008
Posted by Ken Tucker on Tuesday, November 06, 2007 2:43 AM
Permalink | Comments (0) | Post RSSRSS comment feed