Code is repeatedly used in WPF and Silverlight 2.

Source: Internet
Author: User
Tags mscorlib silverlight

Dino Esposito

Code download location: CuttingEdge2008_10.exe (604 KB)
Online browsing code

This column is based on the prerelease version of Silverlight 2. All information in this document may be changed.

Directory

Compatibility between WPF and Silverlight 2
Introduction to visual status Manager
Share code
Inferences about WPF applications
Compile cross-platform WPF code
Analyze managed code
Get policies for key code
Sample Analysis
Final considerations

In Silverlight 2, you can use eXtensible Application Markup Language (XAML) to design and render user interfaces. At the same time, you can use the built-in core CLR to process the hosted code in the browser. In this way, the Web-based Silverlight 2 application is very similar to the desktop Windows Presentation Foundation (WPF) application. One of the benefits of similar programming models is that code can be easily reused between the two. In this column, I will introduce several patterns that allow you to easily share code and XAML markup between Silverlight 2 and WPF.

CoreCLR in Silverlight

Silverlight 2 does contain a CLR, but it is not used by other. NET Applications and assemblies. Silverlight CLR, also known as CoreCLR, fully considers different purposes during design. CoreCLR is designed for cross-platform interoperability. It can run at the same time with CLR and support different security models and different versions of basic class libraries. This is described in detail in the excellent column CLR comprehensive and thorough analysis in August 2008 (see msdn.microsoft.com/magazine/cc721609 ).

Using different CLR for Silverlight and. NET applications means that you cannot reference the same assembly in two projects for. NET Applications and Silverlight applications. The main problem lies in the mscorlib assembly. The functional set required for normal use of Silverlight is very small-only the kernel. However, any. NET assembly must be linked to the standard version of mscorlib, which is the problem.

In the example application discussed in this column, I use an interface to share the Windows Presentation Foundation application and Silverlight application. The only solution is to copy C # And interface definitions between the two projects. because you do not have the Assembly to be referenced together. in the. NET Framework version, it is necessary to divide the functions in the standard mscorlib assembly into two parts: Kernel transactions and desktop transactions, for Silverlight and.. NET sets.

Compatibility between WPF and Silverlight 2

Following the introduction of Silverlight 2, XAML becomes a new generation of UI module APIs. Silverlight 2 supports a subset of the complete WPF framework, including rich layout management, data binding, style, media, animation, graphics, and template functions.

However, fully supported XAML in Silverlight 2 is limited by the size of downloadable plug-ins. Within a few megabytes (less than 5 MB in Beta 2), The Silverlight 2 plug-in must provide the core CLR, that is, including WPF and Windows Communication Foundation (WCF) client platform subset, XAML analyzer, and Microsoft. NET Framework 3.5.

The WPF 3D graphics function is not supported in Silverlight 2, and some attributes and elements have been discarded or dropped. To sum up, you already have a compatible subset, so you can make a complicated WPF user interface for the Silverlight version. Later, I will go back and discuss the key parts of compatibility.

Note that although Microsoft has added some new APIs in Silverlight, they do not have the corresponding functions in the desktop version of WPF. The most relevant functions include controls (such as DataGrid) and classes (such as WebClient for simple GET style network calls ). These functions will also be added to WPF.

Introduction to visual status Manager

In WPF, another outstanding feature that comes with Silverlight 2 will be added-the visual State Manager (VSM) for controls ). VSM simplifies the development of interactive control templates by introducing visual status and status transition. With the introduction of WPF, developers can customize the appearance and behavior of the WPF control through templates and styles. For example, you can't just change the shape and appearance of a widget. You should also define new behaviors or animations of the widget when you click, get, or lose focus.

With VSM, visual status and status transition will complete some of the work for you. Typical VSM visual States include normal, hover, disable, and focus. You can define a style or shape for each of these States. State Transition is used to define how a control converts from one state to another. You can usually define the conversion through an animation. At runtime, Silverlight will play the corresponding animation and apply the specified style to smoothly switch the control from one status to another.

To define the visual status, insert a tag segment in the control template as follows:

Copy code

<vsm:VisualStateManager.VisualStateGroups>  <vsm:VisualStateGroup x:Name="CommonStates">    <vsm:VisualState x:Name="MouseOver">      <Storyboard>        ...      </Storyboard>    </vsm:VisualState>  </vsm:VisualStateGroup></vsm:VisualStateManager.VisualStateGroups>

Each control defines one or more States, such as CommonStates and FocusStates. Each group defines specific visual states, such as "MouseOver", "Pressed", and "Checked ". For conversions between each visual state and state, you can define a storyboard that Silverlight can play automatically when appropriate.

In short, WPF has many functions not supported by Silverlight 2, and many of the functions in Silverlight 2 are not supported by WPF. To a large extent, these differences affect the compatibility at The XAML level. You can use public subsets for full compatibility, and it is good enough to ensure that you can perform almost all the operations.

Share code

When the desktop version of WPF supports VSM, you can use the same method for Silverlight and Windows desktop applications and share control templates between the WPF and Silverlight projects. Before that, let's take a look at how you can reuse code between a WPF desktop and a Web project.

The WPF application consists of XAML and managed code. The purpose of the managed code is to support multiple. NET classes. You should use a common subset of XAML that can be understood by both desktop WPF and Silverlight 2. Similarly, you should organize your code hiding classes to better handle the differences between backend frameworks.

You mainly want to reuse the WPF code in two scenarios. One scenario is that you now have a WPF desktop application that you want to provide on the Web to simplify maintenance and deployment. Another scenario is that you want to develop a front-end for the existing system and apply it to Windows and Web clients.

From the perspective of WPF to Silverlight, I will handle the issue of reusing code. There is a very small difference between refactoring code and marking patterns.

Inferences about WPF applications

A typical WPF application is built through an object tree (Window is the root of the tree. The Window element also contains a large number of child elements arranged and stacked in various ways. These elements involve basic shapes, layout managers, storyboards, and controls (including custom third-party and user controls ). The following is a basic example:

Copy code

<Window x:Class="Samples.MyTestWindow"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    Title="Test App" Height="300" Width="350">    <StackPanel Margin="10">        ...    </StackPanel></Window>

The Code cannot be merged into the Silverlight 2 application as it is. First, the Window element is not supported in Silverlight. In the Silverlight assembly, classes such as System. Windows namespaces are not found at all. The root flag of all Silverlight applications is UserControl. This element is mapped to the UserControl class defined in the System. Windows. Controls namespace.

The following is a title modified Silverlight application:

Copy code

<UserControl x:Class="Samples.MyTestWindow"    xmlns="http://schemas.microsoft.com/client/2007"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    Title="Test App" Height="300" Width="350">    <StackPanel Margin="10">        ...    </StackPanel></UserControl>

<Window> and <UserControl> All tag codes within the element boundary should continue to match. You are responsible for modifying the original desktop XAML so that it meets the requirements of the Silverlight XAML analyzer. This task will benefit a lot from the high compatibility of the two syntaxes. In most cases, adjusting XAML only fixes a few elements and attributes. Two examples are provided.

Desktop WPF contains a <label> element that cannot be recognized by Silverlight. When you migrate this tag to Silverlight, you need to find a workspace for the tag. A rectangle containing text blocks is a feasible solution.

In WPF, you can use the ToolTip property to associate the ToolTip with the control, as shown below:

Copy code

<Button Tooltip="Click me" ... />

The ToolTip attribute is not supported in Silverlight 2. You must use ToolTipService, as shown in the following code snippet:

Copy code

<Button ToolTipService.ToolTip="Click me" ... />

Note that both solutions run in desktop WPF. In addition, ToolTipService in desktop WPF provides a large number of additional tooltip attributes, such as location, offset, initial latency, and duration. However, Silverlight does not support any additional attribute.

Are these compatibility issues between WPF and Silverlight? This depends on how you use WPF. It is usually difficult to migrate important WPF applications to Silverlight. In fact, this is not even our main purpose. First, there are no triggers in Silverlight 2, and you may need them anywhere. For example, the UI element contains a trigger set-child of FrameworkElement, but not in the style, data, and control template.

In the same way, Silverlight supports data binding, but different from WPF. For example, you have a binding element, that is, a data environment, a data template, and a visible set. As mentioned above, you do not have any triggers, but simplified XAML markup requires you to write code more frequently than in WPF. In addition, the internal implementation is completely different. Compared with WPF, the binding object in Silverlight has fewer attributes.

Globalization may lead to another headache for you. For performance reasons, the core CLR does not include global data in all its own supported regions. The cultureinfo class in Silverlight depends on the globalization function provided by the basic operating system. This means that you cannot apply the same global settings across different operating systems.

Finally, WPF includes a richer set of controls, but Silverlight does not. A good example is the RichTextBox Control.

In summary, migrating A Silverlight application to WPF is of little value, although as a developer you should be involved in dealing with potential performance problems that may be caused by rich object models. One thing to remember is that Silverlight supports a subset of possible situations provided by desktop WPF. You are responsible for deciding whether to design a cross-platform solution by selecting the appropriate features.

Compile cross-platform WPF code

The easiest way to migrate code from a WPF project to a Silverlight project is to use user controls. In addition to XML Namespaces and tag differences, using user controls is the only way to share tags and code between desktops and web-based WPF.

If your WPF application is organized on a local machine or can be reconstructed, it is much easier to migrate code to Silverlight by fully utilizing user controls than other methods (cut and paste.

In this way, can the Assembly be shared between the WPF and Silverlight projects? In Silverlight 2, you can certainly create custom class libraries packaged into the assembly. However, you should be aware that these libraries target the Silverlight version of. NET Framework and use different security models (for more information, see complete and thorough parsing of CLR in this month's journal ).

All the Assemblies you use in the desktop WPF application must be re-compiled into the Silverlight class library to ensure that they can reference the correct assembly and call classes legally. Obviously, calls to unsupported classes will be fixed during the re-compilation process, resulting in additional work.

In short, you only need a small amount of work to obtain the WPF application, and use Silverlight to publish it through the Web. If you use this method, the code is actually published on many non-Windows platforms, and the client does not have to install the complete. NET Framework.Figure 1A simple WPF independent desktop application is displayed.Figure 2Displays the same application hosted in Internet Explorer through Silverlight.

Figure 1Sample WPF Application

Figure 2WPF applications for Silverlight(Click an image to view the larger image)

Analyze managed code

For some reason, code reuse between WPF and Silverlight is considered a XAML problem. As mentioned above, some XAML problems are encountered when adjusting the code, but the biggest problem is the code hiding class.

In Windows and Silverlight, XAML files are paired with code hidden classes written in C # or other hosting languages. Unfortunately, these hidden classes are for different versions of the. NET Framework. The desktop version of WPF depends on the. NET Framework 3.5 full base class library (BCL), while Silverlight 2 uses the lightweight version of bcl.

The Silverlight version of BCL is obviously small, but it still supports some basic functions, such as set, reflection, regular expression, string processing, thread, and timer. You also have some tools for calling various services (such as XML Web Services, WCF services, and ADO. NET data services. In addition, rich network support allows you to communicate over HTTP-using Plain Old XML (POX) and stateful transmission (REST) services, usually reaching any public HTTP endpoint. The Network also supports (cross-origin) sockets and duplex communication.

Finally, Silverlight BCL can work well with XML data, including XmlReader and XmlWriter in Special versions. These classes are very similar to similar classes in the. NET Framework of the desktop version.

With these core functions, Silverlight 2 fully supports LINQ to Objects, LINQ to XML, and Expression Tree. Starting from Beta 2, Microsoft also added the brand new LINQ to the JavaScript Object Notation (JSON) provider to directly run the LINQ query on JSON data.

Note that such networking can only happen asynchronously in Silverlight. To make synchronous calls, you need to call the browser's Interoperability layer and implement XMLHttpRequest from the browser as much as possible (for more information, see go.microsoft.com/fwlink /? LinkId = 124048 ).

The main problem is that the WPF and Silverlight code hiding classes use different class libraries. This fact hinders reusability than any XAML difference. Next we will solve the problem.

Get policies for key code

When writing code that will be shared by Silverlight and Windows runtime, you should be very familiar with the support objects of each platform. Ideally, you will get a list of request tasks that require special processing on each platform. Next, isolate the code snippets in the object and extract an interface from it.

In this way, you will get a fully reusable code block, which can call independent components of key functions. Then, migrating such applications to Silverlight (or WPF) becomes as easy as replacing key components with other platform-specific components. Because all these components still expose a public interface, their implementation is transparent to the main code block.

The mode based on this method is the "Policy" mode. For the formal definition of this method, see go.microsoft.com/fwlink /? Linkid = 124047. In short, the "Policy" mode is useful when you need to dynamically change the operations that are used to execute a specific task in an application.

When you have identified the code regions that may change according to the running status, you can define the interfaces used to specify the abstract behavior of the Code. Next, create one or more policy classes to implement this interface to indicate various methods that can complete these abstract behaviors. When you change the policy class, you only need to change the method for solving the operation defined for this interface. In this way, the actual implementation (policy) of the behavior can be separated from the code that uses it.

For example, in ASP. NET, the "Policy" mode is often used to implement the provider model, such as Members, roles, and user configuration files. When ASP. NET is running, it knows that a specific interface needs to be processed, that is, members and users. You can also learn how to find and instantiate specific classes of these interface types. However, the runtime component only depends on the interface, which makes the detailed information of the specific class irrelevant to ASP. NET.

Sample Analysis

Let's analyzeFigure 1And2. In Silverlight and windows, this application provides a form for users to enter the stock code to get the current offer.Figure 3Displays the icon of the application when the user clicks the button. The user interface uses Model-View-Presenter (MVP) mode to pass all the UI background logic in a single presenter class. The quoteservice class is called by the token, which provides the stockinfo object with all the information to be merged into the user interface to provide the final response (seeFigure 4).

Figure 3Action diagram of the application(Click an image to view the larger image)

Figure 4 device class

Copy code

namespace Samples{    class SymbolFinderPresenter    {        // Internal reference to the view to update        private ISymbolFinderView _view;        public SymbolFinderPresenter(ISymbolFinderView view) {            this._view = view;        }        public void Initialize() { }        // Triggered by the user's clicking on button Find        public void FindSymbol() {            // Clear the view before operations start            ClearView();            // Get the symbol to retrieve             string symbol = this._view.SymbolName;            if (String.IsNullOrEmpty(symbol)) {                _view.QuickInfoErrorMessage = "Symbol not found.";                return;            }            QuoteService service = new QuoteService();            StockInfo stock = service.GetQuote(symbol);            // Update the view            UpdateView(stock);        }         private void ClearView() {            _view.SymbolDisplayName = String.Empty;            _view.SymbolValue = String.Empty;            _view.SymbolChange = String.Empty;            _view.ServiceProviderName = String.Empty;        }        private void UpdateView(StockInfo stock) {             // Update the view            _view.QuickInfoErrorMessage = String.Empty;            _view.SymbolDisplayName = stock.Symbol;            _view.SymbolValue = stock.Quote;            _view.SymbolChange = stock.Change;            _view.ServiceProviderName = stock.ProviderName;        }     }}

The QuoteService class does not try to retrieve the quotation by itself. It first creates a provider and then relies on it to work. The QuoteService class executes a very simple operation. If an Internet connection exists, it uses the public Web service provider class to obtain financial data. Otherwise, it will be transformed into a pseudo provider that only returns random numbers. Therefore, the QuoteService class sometimes needs to detect Internet connections, suchFigure 5.

Figure 5 QuoteService checks Internet connections

Copy code

public StockInfo GetQuote(string symbol){    // Get the provider of the service    IQuoteServiceProvider provider = ResolveProvider();    return provider.GetQuote(symbol);}private IQuoteServiceProvider ResolveProvider(){    bool isOnline = IsConnectedToInternet();    if (isOnline)        return new FinanceInfoProvider();    return new RandomProvider();}

So far, there is no difference between Silverlight and WPF, and all code can be fully reused. To detect Internet connections in. NET, you can use some static methods on the NetworkInterface object. This object is defined in the System. Net. NetworkInformation namespace. Specifically, the GetIsNetworkAvailable method returns a Boolean value indicating whether a network connection exists. Unfortunately, this value does not describe too much about Internet connections. The only way to ensure that the Internet is accessible is to try to ping the host (seeFigure 6).

Figure 6 Use ping to detect Internet connections

Copy code

private bool IsConnectedToInternet(){    string host = "...";    bool result = false;    Ping p = new Ping();    try    {        PingReply reply = p.Send(host, 3000);        if (reply.Status == IPStatus.Success)            return true;    }    catch { }    return result;}

Figure 6The only problem in is that Silverlight 2 does not support this code. (Similarly, this code is not supported by the NetworkInterface object .) You need to isolate this code in the replaceable class (and any other code that you find possible compatibility issues ). (For more information about this restriction, see the CoreCLR sidebar in Silverlight that is included in this issue ). In the source code, I created a utility interface for these methods that may cause problems, and then created a policy class to implement the interfaces of various platforms, suchFigure 7.

Figure 7 components used to detect Internet connections

Copy code

public partial class SilverCompatLayer : ICompatLib{    public bool IsConnectedToInternet()    {        string host = "...";        bool result = false;        Ping p = new Ping();        try        {            PingReply reply = p.Send(host, 3000);            if (reply.Status == IPStatus.Success)                return true;        }        catch { }        return result;    }    public string GetRawQuoteInfo(string symbol)    {        string output = String.Empty;        StreamReader reader = null;        // Set the URL to invoke        string url = String.Format(UrlBase, symbol);        // Connect and get response        WebRequest request = WebRequest.Create(url);        WebResponse response = request.GetResponse();        // Read the response        using (reader = new StreamReader(response.GetResponseStream()))        {           output = reader.ReadToEnd();           reader.Close();        }        return output;    }    // A few other methods that require a different implementation     // (See source code)    ...}

The interface here separates the platform-specific policy class from the bearer application. Then you can hide the code that instantiates a specific policy class after the factory method. The following code can be safely used in WPF and Silverlight:

Copy code

private bool IsConnectedToInternet(){    ICompatLib layer = ServiceResolver.ResolveCompatLayer();    return layer.IsConnectedToInternet();}

The silvercompatlayer class exists in an independent assembly. When migrating WPF code to Silverlight, you need to change this Assembly, and vice versa.

After creating the required platform-specific policy classes, all the remaining tasks are to create the Silverlight version of the application. The Silverlight project derived from the original WPF application contains a precise copy of all files except the compatible assembly.

In the associated download code in this article, you will notice that I explicitly instantiate a specific class in the factory method to determine which policy implementation to use. You can instantiate the class directly like this, or read their names from the configuration file, and then get the instance using reflection. The Implementation Details mainly depend on the type of the system you are building. In terms of the WPF-to-Silverlight compatibility, policies and layers are key concepts to be understood.

Final considerations

In the example application, I made a network call. In the original WPF application, the call is a synchronous call. However, in Silverlight 2, synchronous network calling is not supported at all. The only method for Synchronous calling is to call the XMLHttpRequest browser (for more information, see source code ).

In the sample code, I successfully migrated the original WPF application to the Web. During code migration, you may want to take into account the local functions of the Silverlight environment and modify the structure of the application during adjustment. Note that in my simple example, it takes much less code and work to rewrite the application using the Silverlight programming model than to adapt the application based on the WPF application.

Therefore, WPF and Silverlight have many commonalities in pure visual programming languages (such as XAML. However, the basic programming model is slightly different. Effective solutions in WPF are not necessarily suitable for Silverlight, and vice versa. That is to say, the XAML and code sharing between WPF and Silverlight applications must be implemented.

Please send your questions and comments to Dino to the cutting@microsoft.com.

Dino EspositoCurrently, it is an IDesign architect and also the Programming ASP. NET 3.5 Core Reference.. Dino has settled in Italy and often gives speeches during industry events around the world. You can join his blog at weblogs.asp.net/despos.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.