WPF Introduction

WPF is short for Windows Presentation Foundation. Microsoft takes it as a next-generation presentation system for building Windows client applications with visually stunning user experiences. Obviously, the “next” is compared with MFC; a presentation system for windows before WPF. WPF brings in many new features for developers.

1)      DirectX instead of GDI/GDI+/user32

To achieve a visually stunning UI efficiently, WPF uses DirectX as its graphic engine instead of GDI/GDI+/User32. The difference between them is that DirectX has hardware acceleration while GDI/GDI+/User32 does not. That means that DirectX can use the GPU to do part of the rendering work while GDI/GDI+/User32 can only use the CPU to complete entire rendering work. When dealing with complex textures, special effects such as partial transparency, anti-aliasing, and three-dimensional graphics, a GPU is much faster than a CPU. Indeed, DirectX is designed as a game developer’s toolkit and is supported by all the modern video cards, so a WPF application can easily implement excellent graphics effects similar to those used in games. But in some cases, such as when the DirectX version level is lower than 9, a WPF application doesn’t have hardware acceleration. Open the site http://msdn.microsoft.com/en-US/eng/library/ms742196(v=vs.110).aspx  for all the cases.

WPF Graphic Engine

2)      Data-Driven

In old presentation systems such as MFC, data is used by the UI. When a datum is modified, the UI doesn’t update until a refresh function is called. On the contrary, WPF is a data-driven system. The change of a datum would cause the UI to refresh automatically if the datum is a Dependency Property and AffectsArrange is true. Also, the change of UI would cause the change of data automatically if there is a two-way binding between them.

 WPF Data Driven

3)      Resolution Independence

Traditional windows applications are bound by certain assumptions about resolution. Developers usually assume a standard monitor resolution (such as 1366 x 768 pixels), and design the window in mind and try to ensure reasonable resizing behavior for smaller and larger dimensions. The problem is that the application isn’t scalable. As a result, when the application runs on a monitor with higher resolution, the application window will be smaller and more difficult to read. While with lower resolution, the window for the application will be larger and therefore part of the windows will be displayed off-screen [2].

WPF uses device-independent units to measure Windows and other elements, it bases its scaling on the system DPI setting. A unit is defined as 1/96 of an inch. The physical size (the real size when it’s displayed on the monitor) of a unit is calculated as

[Physical Unit Size] = [Device-Independent Unit Size] x [System DPI]

= 1/96 x System DPI (pixels)

= 1/96 x System DPI / Screen DPI (inch)

According to the definition of the unit and calculation of physical unit size, 96 units make up to an inch based on system DPI. But the physical size may not equal to an inch unless System DPI is equal to Screen DPI. To have a comfortable view of the windows, System DPI is always set closely to Screen DPI. So when running on a higher resolution monitor, System DPI is larger and a WPF window keeps its size by rendering it greater detail with more pixels. And a WPF window keeps its size by rendering it with less pixels when the monitor’s resolution is lower.

Note:

1. System DPI: It can be set by Personalize->Display->Smaller-100% (96dpi)/Medium-125% (120dpi)/Larger-150% (144dpi).

2. Screen DPI: A 19-inch LCD monitor with a maximum resolution of 1600 by 1200 pixels. The screen DPI of the LCD monitor is

WPF Resolution Dependency

4)      Declarative User Interface

Except for the traditional ways  of designing user interfaces, such as drag and drop control, and code (C#/C++/other languages), WPF provides another way by using declarative markup language XAML. XAML is very easy and convenient just like HTML. What’s more, it allows the designers and developers to work simultaneously, since the design file (.xaml file) and the code file (.xaml.cs file) are two separate files.

WPF XAML

5)      Style, Resource and Template

WPF provides Style, Resource and Template to modify the appearance of a control. It’s so flexible that developers can get whatever effects they want. What’s more, Style, Resource and Template can be written in a standalone file, so that they can be reused.

6)      Routed Event

In traditional windows application, an event is only raised on the control that gets focus. While in WPF, almost all the UI events are routed events. Routed events can depart into Direct Event, Bubble Event and Tunnel Event according to their routing strategy. A Direct Event behaviors like a traditional event. A Bubble Event is raised from the original source (the control focused) to the outermost parent and a Tunnel Event is raised in the opposite direction. Developers can easily stop the routing process by set e.Handled (e is the EventArgs) true. So developers can easily handle or stop one event in any control along the routing path. It’s very useful in many cases, for example setting a global event.

WPF Routed Event

7)      Command

This is a small feature in WPF. In brief, if there are several events that can be used to perform the same function, such as mouse click, shortcut key and menu, developers can bind the events to one command that performs the function instead of writing an event handle for each event.

WPF Command

8)      Multimedia and Annotation

WPF provides high-level APIs for using multimedia and annotation, such as audio and video. Developers can easily deal with multimedia and annotation with them and design a wonderful rich application.

Reference:

[1]MSDN:http://msdn.microsoft.com/en-us/library/ms754130(v=vs.110).aspx

[2]Pro WPF 4.5 in C#: Windows Presentation Foundation in .NET 4.5, written by

Matthew MacDonald

How to Get the Working Directory in a WPF Project

Yesterday, my colleague told me that there was a weird issue that existed in our WPF sample code for Dynamic .NET TWAIN. What we wanted to implement was to create two projects, and start one application from another. The problem was, when we started the invoked application independently, it worked well. Whereas when it was invoked from another application, none of the UI resources loaded.

ImageBrush dpTitle.Background = new ImageBrush(new BitmapImage(new Uri(imageDirectory + "title.png", UriKind.RelativeOrAbsolute))); // Loading UI resources

Because of this behavior, I thought the resource path might be wrong. After I investigated the source code, I found that our developer used the Property Environment.CurrentDirectory.

Here is the code:

String imageDirectory = Environment.CurrentDirectory.Substring(0, Environment.CurrentDirectory.IndexOf("Samples")) + @"Samples\Bin\Images\WpfDemoImages\";

Refering to Microsoft’s remarks “By definition, if this process starts in the root directory of a local or network drive, the value of this property is the drive name followed by a trailing slash (for example, “C:\”). If this process starts in a subdirectory, the value of this property is the drive and subdirectory path, without a trailing slash (for example, “C:\mySubDirectory”)”, using this property seems to be completely correct.

To verify this issue, I decided to check the directory output in the two different cases.

The output directory for running the app independently:

C:\Users\admin\Desktop\HTTP_Directory\Dynamic .NET TWAIN 5.0 Trial\Samples\Bin\Images\WpfDemoImages\

Start the app from another app:

Process.Start(@"C:\Users\admin\Desktop\HTTP_Directory\Dynamic .NET TWAIN 5.0 Trial\Samples\C# Samples\VS 08\WpfControlsDemo\WpfControlsDemo\bin\Debug\WpfControlsDemo.exe");

Output directory:

C:\Users\admin\Desktop\HTTP_Directory\WPF TEst\WPF TEst\bin\Debug

As you can see, the two result are different. The second output directory is the working directory of the caller application. In this situation, the Property Environment.CurrentDirectory cannot return the expected result.

Is there an alternative? As a matter of fact, Microsoft provides another method. Here is what I found:

String strAssemblyPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
String imageDirectory = strAssemblyPath.Substring(0, strAssemblyPath.IndexOf("Samples")) + @"Samples\Bin\Images\WpfDemoImages\";

This method returns the location of the loaded executable file. Therefore, we can easily find out the relative path of the resource files. Now, our WPF projects can work perfectly.

How to Read Barcode in WPF with VB.NET

We’re proud to reveal that Dynamsoft’s Dynamic .NET TWAIN 5.0 is on its way to release soon. In addition to WinForms support, the new version will include a WPF control. You can use it in your WPF app to capture images from TWAIN scanners and UVC/WIA webcams, to edit and save images to local disks, to a server or a database. Today, I’d like to cover how, using VB.NET, you can use the Dynamic .NET TWAIN 5.0 SDK to implement barcode reading in a WPF application.

The relevant source code can be downloaded here.

Barcode Demo

1.        Create a New WPF Project

First, start Visual Studio .NET, and create a new WPF project. Select Visual Basic as the type and choose WPF Application as the template.

Create WPF Project

2.        Add a Reference

Right-click on the project root, and select Add Reference… from the menu. Click Browse to locate DynamicDotNetTWAIN.dll and add it.

WPF Reference

3.      Add Dynamic .NET TWAIN Component

If there is no Dynamic .NET TWAIN component available, you might need to open the toolbox. To do so, right-click on the panel and select Choose Items… Switch to the tab WPF Components and click Browse… to load DynamicDotNetTWAIN.Wpf.dll

 WPF Component

4.         Add Buttons and Textbox

Next, you’ll want to drag two buttons and one textbox from the toolbox to design a form. The buttons are used to load an image and make the detection of a barcode. And, the textbox is used to display the information decoded from barcode.

WPF Button

5.         Code for Loading Image

Now, what you need to do is to acquire an image using the Windows standard API. Then you’ll need to load it using the Dynamic .NET TWAIN component method. Just a couple of lines of code are needed for loading an image. It’s pretty simple.

       Dim filedlg As OpenFileDialog
        filedlg = New OpenFileDialog()
        filedlg.Multiselect = True
       Dim strFilename As String
        If (filedlg.ShowDialog() = DialogResult.OK) Then
            For Each strFilename In filedlg.FileNames
                DynamicDotNetTwain1.LoadImage(strFilename)
            Next
        End If

6.         Code for Barcode Recognition

To decode a barcode, the path for the barcode library needs to be first be specified. Then, with one additional line of code, you’ll get results.

Set the path of barcode library

        Dim strDllFolder As String
        strDllFolder = Application.ExecutablePath
        Dim pos As Integer
        pos = strDllFolder.LastIndexOf("\Samples\")
        If (pos <> -1) Then
            strDllFolder = strDllFolder.Substring(0, strDllFolder.IndexOf("\", pos)) + "\Bin\BarcodeResources\"
        End If
        Me.DynamicDotNetTwain1.BarcodeDllPath = strDllFolder

Get the results and display them on screen

        Me.TextBox1.Text = ""
        Dim aryResult() As Result
        aryResult = Me.DynamicDotNetTwain1.ReadBarcode(Me.DynamicDotNetTwain1.CurrentImageIndexInBuffer, BarcodeFormat.All)
        Dim strText As StringBuilder
        strText = New StringBuilder()
        If aryResult.Length = 1 Then
            strText.AppendFormat(aryResult.Length & " total barcode" & ("") & " found." & Constants.vbCrLf)
        Else
            strText.AppendFormat(aryResult.Length & " total barcode" & ("s") & " found." & Constants.vbCrLf)
        End If
        For i As Integer = 0 To aryResult.Length - 1
            Dim objResult As Result
            objResult = aryResult(i)
            strText.AppendFormat("      Result " & (i + 1) & Constants.vbCrLf)
            strText.AppendFormat("      BarcodeFormat: " & objResult.BarcodeFormat.ToString() & Constants.vbCrLf)
            strText.AppendFormat("      Text read: " & objResult.Text & Constants.vbCrLf)
        Next i
        Me.TextBox1.Text = strText.ToString()

I hope this brief tutorial is helpful to anyone who is looking for a .NET barcode reader SDK in VB.NET.

For further inquiries, please feel free to send me an email at kgao[at]dynamsoft.com.

Dynamic .NET TWAIN 5.0 is scheduled to be released late next month. To stay informed about all our product announcements, blog posts and more, be sure to follow us on Twitter, like us on Facebook or add us on Google+. Also, if you’d like to be amongst the first to try out the new version first, please contact support[at]dynamsoft.com.