Showing posts with label Silverlight. Show all posts
Showing posts with label Silverlight. Show all posts

Apr 14, 2011

Silverlight 5 Beta Development Tools

Silverlight 5 Beta was announced at MIX11 yesterday. This blog post is an overview of Silverlight 5 development tools. To get started, download following components:

Recommended Downloads

 

VS/VWD 2010 SP1 + SL5Tools

SL4 development requires VS2010 or VWD2010 RTM and SL4Tools, and optionally Blend 4. VS2010 SP1 has SL4 support built in, so SL4Tools is not needed if you’ve already upgraded to VS2010 SP1. SL5 development requires VS2010 or VWD2010 SP1 and SL5Tools, and optionally Blend Preview for Silverlight 5.

Install

SL5 Beta Tools installs Silverlight 5 Beta Developer Runtime, SDK, Update to VS2010 SP1 (KB2502836), and WCF RIA Services V1.0 SP2 Preview.

image

Multi-targeting

Once installed, you can create SL5 projects like you used to with previous versions of SL:

image

SL5 projects can reference assemblies built against early versions of Silverlight. Below screenshot shows a SL5 project using SL4 SDK via Project->Add Reference…–>Browse:

image

And the result in .csproj file:

<Reference Include="System.Windows.Controls, Version=2.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
  <SpecificVersion>False</SpecificVersion>
  <HintPath>..\..\..\..\..\..\..\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Libraries\Client\System.Windows.Controls.dll</HintPath>
</Reference>

Please notice the HintPath and assembly version (Btw, SL5 increased assembly version from 2.0.5.0 to 5.0.5.0).

You can also upgrade existing SL4 projects to target SL5:

image

The upgrade changes <ProjectGuid> and <TargetFrameworkVersion> in .csproj, as well as upgrading all SDK references to SL5’s.

Binding Debugging

A popular new feature in SL5Tools is xaml binding debugging:

image

 

Blend Preview for Silverlight 5

Optionally, you can also install Blend Preview for Silverlight 5, which is basically Blend 4 with SL5 support:

image

And you can use both VS and Blend on the same SL5 project and switch between them:

image

image

 

Troubleshoot & Uninstall

VS2010 SP1, SL5Tools and Blend Preview install all take a long time, so please be patient. If you run into install issues, you may want to take a look at install logs in %temp% directory, and attach those logs when you report install issues to Microsoft:

C:\Users\ningz\AppData\Local\Temp>dir /b /o-d *silver*
Silverlight 5 Beta Tools for Visual Studio 2010 SP1_20110413_220121704.html
Silverlight 5 Beta Tools for Visual Studio 2010 SP1_20110413_220121704-MSI_RiaServices.msi.txt
Silverlight 5 Beta Tools for Visual Studio 2010 SP1_20110413_220121704-MSI_silverlight_sdk.msi.txt
Silverlight0.log

To uninstall Silverlight 5 tools, use control panel to uninstall each component individually:

  • SL5 runtime, SDK, RIA Services, Blend Preview

image

  • And Update to VS2010 (KB2502836) (please click “View installed updates” to see below)

image

 

Enjoy developing against Silverlight 5!

 

Feb 17, 2010

Silverlight Deployment Troubleshooting Guide

After helping a few customers with Silverlight install issues, I think it may be helpful to publish a Silverlight deployment troubleshooting guide and keep it up-to-date, so here you go.

Troubleshooting Steps

  • Is Silverlight installed?
    on Windows, make sure “Microsoft Silverlight” is in Control Panel –> Programs and Features:
    check Silverlight in appwiz.cpl
    On Mac, make sure /Library/Internet Plug-Ins/Silverlight.plugin is there. If Silverlight isn’t installed, you can install the latest version from http://www.silverlight.net or http://www.microsoft.com/silverlight.
  • Is Silverlight enabled?
    For Internet Explorer, select menu item Tools –> Manage Add-ons, make sure Microsoft Silverlight is enabled for all web sites:
    Make sure Silverlight is enabled with IE For Firefox, select menu item Tools –> Add-ons, click Plugins tab, make sure Silverlight Plug-In is enabled:
    Make sure Silverlight is enabled with Firefox
  • Is the issue site specific?
    try http://silverlight.net: if you see the showcase Silverlight application on the top right of the page, then your issue is likely to be site specific, please report the issue to the site owner. O/w, please click the Forums tab at http://silverlight.net page, search and/or report the issue there.  
  • Is the issue browser specific?
    try open the page in a different browser (IE/Firefox/Chrome on Windows, Safari/Firefox/Chrome on Mac) and see whether the issue repros. If it doesn’t repro, it is likely to be a browser specific configuration issue. Again, it may help to search http://forums.silverlight.net to see whether this is a known issue; and if not, report it.

Other Helpful Sources

This is first version, I will keep adding content to the post and keep it up to date with issues I see reported. Thanks!

 

Technorati Tags: ,

Why do I keep getting prompted to install Silverlight?

Issue: a few people get prompted repeatedly to install Silverlight while visiting web sites like nbcolympics.com.

Solution: if you have old version of Webshots Toolbar or Kiwee Toolbar from American Greetings, you should upgrade to latest version from their web sites.

Details:

A few people trying to view Olympics videos from www.nbcolympics.com got prompted to install Silverlight, so they did and then hit F5; the page somehow prompted them to install Silverlight again, so they did again; but this time Silverlight install fails with a telltale error code 1514: Silverlight is already installed; if you want to reinstall, you need to uninstall first. So they uninstall and reinstall, but that didn’t help: they got prompted to install Silverlight again.

After quick investigation, I’ve found a common cause of old version of Webshots or Kiwee installed on those users’ machines. To check, you can find Webshots from Control Panel –> Programs and Features:

start -> run: appwiz.cpl, or control panel -> add/remove programs

or on disk:

AGI files on disk

The fix is to go to www.webshots.com and upgrade to the latest version (3.1.5.7617 for now):

http://www.webshots.com/page/apps?app=anonhomepage&vhost=www

then you should be able to watch Olympics video just fine with Webshots toolbar enabled as well:

Silverlight + WebShots in IE

Silverlight + WebShots in FF

I will publish another blog post with common setup issues and solutions for Silverlight.

Disclaimer:

  • I am publishing this blog in a hurry to help those with trouble viewing Olympics video, so I may not get all facts right. I’d appreciate all feedback/correction/suggestion.
  • This is my personal blog. What I say in this blog is my opinion only. It doesn’t represent Microsoft or any other organization.
Technorati Tags: ,

Nov 30, 2009

Silverlight Design Time Assemblies

Introduction

If you write Silverlight controls, you should consider writing design time assemblies for your controls too, for two simple reasons:

  • developer productivity: try to imagine Silverlight development without tools like Visual Studio or Blend! For custom controls, you may need to provide much of the design time experience for your controls in Visual Studio or Blend yourself.
  • designers: XAML and tools like Blend enable developers and designers work together. A key design criteria for Silverlight controls is to make sure designers can use them without writing a single line of code.

Design time experience usually includes (but not limited to) the following:

  1. Metadata for property window, like category, infotip, property editor, binding etc.
  2. Metadata for design surface, like initializer, adorner, context menu, adapters etc.
  3. Toolbox integration, like icons, control registration
  4. intellisense for code editor

Except intellisense (please see Add Rich Intellisense for Your Silverlight Controls) and control registration (please see Register Silverlight Controls with visual Studio and Blend), above design time experience are usually delivered through design time assemblies. Below I will discuss various approaches of delivering design time experiences, in increasing complexity and flexibility, and gradually introduce pieces of the naming convention of design time assemblies.

Runtime Assembly Only

The simplest way to deliver design time experience is to package design time code into the runtime assemblies, especially when design time metadata are meaningful at runtime too, like TypeConverterAttribute.

The pros and cons of this approach:

  • Pro: simple
    • no separate design time assemblies, simpler setup
    • design time attributes are specified directly on the runtime code, easier to maintain
  • Con: tight coupling of runtime and design time code
    • perf degradation because of useless design time code at runtime
    • design time dependencies (like MWDs and other VS/Blend assemblies) get dragged into runtime unnecessarily
    • can’t service runtime or design time independently
    • can’t support multiple designers (like both VS2008/Blend2 and VS2010/Blend3)
    So this approach is highly discouraged, unless there is strong justification for it.

Shared Design Time Assembly

So the revolutionary step forward is to decouple design time and runtime code, release and service them with separate assemblies. This opens up all kinds of possibilities. Of course, we need a way to link design time assemblies to their corresponding runtime assemblies, without introducing any unnecessary dependency or perf degradation to runtime assemblies. Hence the naming convention: if a runtime assembly Foo.dll is referenced in a Silverlight project, the designer (like Visual Studio and Blend) will first try to load design time information like icons (via another naming convention, see How to Add an Toolbox Icon for Your Silverlight Control) and design time metadata (via interface, like IRegisterMetadata for VS2008 and Blend2, or IProvideAttributeTable for VS2010 and Blend3. Please see How to Write Silverlight Design Time for All Designers: Visual Studio 2008, Blend 2; Blend 3, and Visual Studio 2010) from the runtime assembly; it will then look for a design time assembly by the name Foo.Design.dll in the same directory as Foo.dll; if found, the designer will try to load design time information from Foo.Design.dll as well.

Designer Specific Design Time Assembly

Visual Studio is mostly for developers, while Blend is mostly for designers, so they have difference requirements for design time experiences. Putting all design time code in one shared design time assembly introduces tight coupling among designers. So the naming convention is enhanced: for runtime assembly Foo.dll, there is a shared design time assembly Foo.Design.dll that’s loaded by all designers; each designer will also try to load its own design time assemblies, like Foo.VisualStudio.Design.dll for Visual Studio, and Foo.Expression.Design.dll for Blend. The designer specific design time assembly is loaded after the shared design time assembly. Third party designers can define their own designer specific design time assembly. 

Design Sub Folder

So to support both Visual Studio and Blend, each runtime assembly has three design time assemblies, in the same directory, and a package (like Silverlight SDK or Silverlight Toolkit) usually contains several runtime assemblies. So the directory gets a bit crowded. A minor improvement is to put the design time assemblies under a Design subfolder. So the naming convention is further enhanced: if a designer (like Visual Studio or Blend) can’t find corresponding design time assemblies in the same directory as a runtime assembly, it will look for them in the Design subfolder, if it exists. 

Support Multiple Versions of MWDs

Design time are built on top of designer extensibility framework, which consists of several dlls like Microsoft.Windows.Design.Extensibility.dll and Microsoft.Windows.Design.Interaction.dll. We usually call them collectively as MWDs. To make life more interesting, sometimes we have to introduce breaking changes to the extensibility framework, like VS2008 and Blend2 use MWD version 3.5, VS2010 and Blend3 use MWD version 4.0, and they are incompatible. So if you have a runtime assembly Foo.dll, and you want your users to be able to develop against it with both VS2008 and VS2010, you have to provide two sets of design time assemblies: one set built against v3.5 MWDs and used by VS2008, and another set built against v4.0 MWD and used by VS2010. The two sets of design time assemblies probably have a lot of code in common, while the one for VS2010 may have some new code to leverage the new functionalities exposed by VS2010. Since design time assemblies are loaded by name and you can’t have two files with the same name, so the naming convention is enhanced yet again:

for a runtime assembly Foo.dll, the shared design time assembly is named Foo.Design*.dll, the Visual Studio specific design time assembly is named Foo.VisualStudio.Design*.dll, and the Blend specific design time assembly is named Foo.Expression.Design*.dll, where * can be zero or more valid characters for file names. When a designer (like Visual Studio or Blend) tries to load a design time assembly and several fit the naming convention, zero or one will be loaded:

  • If the MWD version referenced by the design-time assembly has a different major version number than the designer’s MWD version, then the design-time assembly will not load and is bypassed.
  • If more than one design-time assembly is compatible with the designer’s MWD version, the Designer loads the one compiled against the highest MWD version that is less than or equal to the designer’s MWD version.

Please see Extensibility Series – WPF & Silverlight Design-Time Code Sharing – Part I and How to Write Silverlight Design Time for All Designers: Visual Studio 2008, Blend 2; Blend 3, and Visual Studio 2010 for more information.

Support Both WPF and Silverlight

To complicate life further, since WPF and Silverlight are so awfully similar, you may be tempted to try to write it once and run with both WPF and Silverlight. You are not alone. There are many articles on how to share source code and/or binaries across Silverlight and WPF. We’d like to do that for design time assemblies too. One approach is to make most of the design time assemblies platform agnostic, and limit platform specific (WPF or Silverlight) code and references to a small platform specific assembly. Please see Extensibility Series – WPF & Silverlight Design-Time Code Sharing – Part I for more information on this.

Last One Wins

The same design time metadata for a class or its member can be specified multiple times in multiple design time assemblies, which allows the shared design time assembly to specific the default/common behavior and then designer specific design time assemblies to override it if necessary. The same design time metadata can also be specified multiple times within a single design time assembly (please see Design Time Feature Implementation in Silverlight Toolkit as an example, where DescriptionAttribute for a class or its property can be added by AddDescriptions, AddAttributes and AddTables methods). So we need to know which metadata wins. The simplest and most logic design is that last one wins. This is mostly true but not always. Sometimes the result is un-deterministic when the same design time metadata is specified several times but with different values.

Feedback

Devil is in the details! Feedbacks are always appreciated. Please let me know what issues you run into, what requests/improvements you’d like to make, for both design times experience and designer extensibility framework. Thanks!

 

Nov 28, 2009

Silverlight Drag and Drop API

Introduction

Drag and drop is a common UX paradigm and a top requested feature. In Silverlight 4 Beta, we introduced a basic set of API to enable the most common scenario of dragging pictures files and dropping them to Silverlight applications, and we designed the API to allow us to expose more drag and drop functionalities down the road without API change, hopefully.

API

Below is the core of the new API:

namespace System.Windows
{
public abstract class UIElement : DependencyObject
{
// Fields
public static readonly DependencyProperty AllowDropProperty;

// Events
public event DragEventHandler DragEnter;
public event DragEventHandler DragLeave;
public event DragEventHandler DragOver;
public event DragEventHandler Drop;

// Properties
public bool AllowDrop { get; set; }
}

public delegate void DragEventHandler(object sender, DragEventArgs e);

public sealed class DragEventArgs : RoutedEventArgs
{
// Methods
public Point GetPosition(UIElement relativeTo);

// Properties
public IDataObject Data { [SecuritySafeCritical] get; }
public bool Handled { get; set; }
}
}

namespace System.Windows.Controls
{
public abstract class Control : FrameworkElement
{
protected virtual void OnDragEnter(DragEventArgs e);
protected virtual void OnDragLeave(DragEventArgs e);
protected virtual void OnDragOver(DragEventArgs e);
protected virtual void OnDrop(DragEventArgs e);
}
}

  • AllowDrop: this is dependency property, indicating whether an element is a drop target.
  • DragEnter, DragLeave, DragOver & Drop: these are routed events. They bubble up, and fire only on elements with AllowDrop set to true.
  • OnDragEnter, OnDragLeave, OnDragOver & OnDrop: these are protected virtual functions for subclasses to override. 
  • DragEventArgs: this class allows drop target event handlers or method overrides to access the data being dragged or dropped.

Usage

There are primarily two ways to use Silverlight’s drag and drop API:

  • Silverlight applications can handle those drop target events and process the files dropped in the event handlers.
  • Silverlight controls can override those drop target virtual functions to process the data being dragged and dropped, and enable themselves to be drop targets.

Limitations

The drag and drop functionality shipped in Silverlight 4 Beta only enables the most common scenario: Silverlight plugin as a file drop target. Please notice the following limitations with current implementation:

  • there is no drop source support (QueryContinueDrag & GiveFeedback).
  • there is no DragDropEffects or DragDropKeyStates in DragEventArgs.
  • there is no visual for the dragged object or DragDropEffects.
  • only file drag and drop is supported:
    • all drop target events fire only when files are being dragged and dropped.
    • IDataObject, DataObject and DragEventArgs.Data support only one format: “FileDrop”, and the data is of type FileInfo[].
  • most of IDataObject methods throw NotImplementedException.
  • for drag and drop to work on Windows, Silverlight plugin must be windowed. In another word, if <param name="windowless" value="true"/> is specified, drop events won’t fire.
  • since Silverlight plugin on Mac is always windowless, you need to hook up JavaScript drop events to trigger Silverlight drop events. In another word, if you want your Silverlight application to support file drop on Mac as well as Windows, you will need to add following script and Silverlight plugin attributes to the hosting html or aspx page:
    <!-- add following script before end of HEAD tag -->
    <script type="text/javascript">
    function handleDragEnter(oEvent) {
    // Prevent default operations
    oEvent.preventDefault();

    var flag = silverlightControl.dragEnter(oEvent);

    // If we handled it successfully then stop propagation of the event
    if (flag)
    oEvent.stopPropagation();
    }

    function handleDragLeave(oEvent) {
    // Prevent default operations
    oEvent.preventDefault();

    var flag = silverlightControl.dragLeave(oEvent);

    // If we handled it successfully then stop propagation of the event
    if (flag)
    oEvent.stopPropagation();
    }

    function handleDragOver(oEvent) {
    // Prevent default operations
    oEvent.preventDefault();

    var flag = silverlightControl.dragOver(oEvent);

    // If we handled it successfully then stop propagation of the event
    if (flag)
    oEvent.stopPropagation();
    }

    function handleDropEvent(oEvent) {

    // Prevent default operations
    oEvent.preventDefault();

    var flag = silverlightControl.dragDrop(oEvent);

    // If we handled it successfully then stop propagation of the event
    if (flag)
    oEvent.stopPropagation();
    }
    </script>
    <!-- use JavaScript drop target events to trigger Silverlight's drop target events -->
    <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%"
    id="silverlightControl" ondragenter="handleDragEnter(event)" ondragover="handleDragOver(event)"
    ondragleave="handleDragLeave(event)" ondrop="handleDropEvent(event)" >


  • DragEventArgs.Data is only accessible in Drop event. Accessing DragEventArgs.Data in DragEnter, DragOver and DragLeave may cause SecurityException. And accessing Directory, DirectoryName or FullName property of the FileInfo object from DragEventArgs.Data may cause ArgumentNullException. 

    Demo App

    Below is a demo app:
  • the top left nested grids use drop target event handler to display DragEventArgs info.
  • the top right nested grids contain an ImageDropTarget user control, which overrides OnDrop method to render the dropped file if it is an image.
  • the bottom listbox shows the sequence of drop target events, their bubbling up, and DragEventArgs info.
    DragDropDemo

    you can find the complete source here.

    Feedback

    While we are excited to add drag and drop to Silverlight, we know there are a lot to finish/improve, and what we released is just a Beta. As always, your feedback is highly appreciated, and will be used as an important data point to help us prioritize the work. Thanks!

     

    Technorati Tags: ,

    Nov 18, 2009

    Silverlight 4 Adds Arabic Support

    Silverlight 4 adds support for Arabic culture:

    • Install, configuration and runtime UI are in Arabic and RTL layout on Arabic culture
    • Support mixed BiDi/ComplexScript text
    • Support RTL layout with FlowDirection attribute and implemented by all controls

    Below screenshots demonstrate some of the support:

    • Install UI:
      Silverlight developer runtime install UI
    • Configuration UI:
      Silverlight Configuration UI
    • Controls with FlowDirection set to RightToLeft:
      RTL Layout and Controls Demo

    For those curious, you may notice that:

    • there is a new ar directory under %programfiles%\Microsoft Silverlight\4.0.41108.0, besides the 10 directories that have been there since SL3: de, en-us, es, fr, it, ja, ko, zh-Hans, zh-Hint. The ar directory contains Arabic resources for Silverlight runtime assemblies.
    • the MUI resource dlls contain Arabic resources:
      image

    We will continue adding more support to more cultures in Silverlight. The Arabic support debuted in Silverlight 4 Beta is particularly important, since it is the first RTL language Silverlight supports. If you notice any bug or have suggestions, please let me know.

    Technorati Tags: ,

    Silverlight Clipboard API

    Clipboard API in Silverlight

    Silverlight 4 adds Clipboard support. Check out the amazing demos by Scott Guthrie and Brian Goldfarb today at PDC that showcase scenarios enabled by Silveilght4 Clipboard support.

    Silverlight’s Clipboard API is a subset of WPF’s Clipboard API: 

    public static class Clipboard
    {
    public static bool ContainsText();
    public static string GetText();
    public static void SetText(string text);
    }
    It allows copy/paste Unicode strings to/from system clipboard. GetText and SetText require either of following to succeed:
    1. the calling Silverlight application is an elevated trust application, or
    2. it is user initiated and user grants clipboard access
    For the second case, when GetText or SetText is first called in an user initiated event handling, Silverlight pops up a dialog like the one below (UI may change at RTW):
      Clipboard Prompt
      If user clicks yes, Silverlight will allow this and later GetText/SetText calls to succeed for this application during this session; if user clicks no, the default, Silverlight will throw a SecurityException. In another word, the setting is per application, per session, for both get and set access to system clipboard, and it is not persisted.

    Clipboard API in JavaScript and WPF

    We need to consider many factors while designing Clipboard API for Silverlight. Among them, the Clipboard APIs of JavaScript and WPF are particularly interesting, because we need to study the security lessons in JavaScript and try to be compatible with WPF.

    There is no cross browser, cross platform JavaScript API for clipboard access. IE provides clipboardData object that allows get/set/clear strings in system clipboard:

    bResult = window.clipboardData.setData(sDataFormat, sData);
    sData = window.clipboardData.getData(sDataFormat);
    bResult = window.clipboardData.clearData([sDataFormat]);

    where sDataFormat is a string constant of "Text" or "URL", sData is a string, and bResult is a Boolean.

    The first time the clipboadData object is accessed, IE will prompt user to allow the script to access clipboard, and the setting is valid for the session only.

    WPF’s Clipboard API supports more and extensible data format via IDataObject, and has helper functions for common formats like text, image, audio, and filedrop.

    public static class Clipboard
    {
    // Methods
    [SecurityCritical]
    public static void Clear();
    public static bool ContainsAudio();
    public static bool ContainsData(string format);
    public static bool ContainsFileDropList();
    public static bool ContainsImage();
    public static bool ContainsText();
    public static bool ContainsText(TextDataFormat format);
    public static Stream GetAudioStream();
    public static object GetData(string format);
    [SecurityCritical]
    public static IDataObject GetDataObject();
    public static StringCollection GetFileDropList();
    public static BitmapSource GetImage();
    public static string GetText();
    public static string GetText(TextDataFormat format);
    public static bool IsCurrent(IDataObject data);
    public static void SetAudio(byte[] audioBytes);
    public static void SetAudio(Stream audioStream);
    public static void SetData(string format, object data);
    [SecurityCritical]
    public static void SetDataObject(object data);
    [SecurityCritical]
    public static void SetDataObject(object data, bool copy);
    public static void SetFileDropList(StringCollection fileDropList);
    public static void SetImage(BitmapSource image);
    public static void SetText(string text);
    public static void SetText(string text, TextDataFormat format);
    }

    Clipboard API in Windows and Mac OS X

    Silverlight’s clipboard API is ultimately implemented on top of the clipboard APIs of the underlying operating system. Windows’ clipboard APIs are documented at MSDN, below excerpt gives an overview on how to set/get clipboard data:

    Cut and Copy Operations

    To place information on the clipboard, a window first clears any previous clipboard content by using the EmptyClipboard function. This function sends the WM_DESTROYCLIPBOARD message to the previous clipboard owner, frees resources associated with data on the clipboard, and assigns clipboard ownership to the window that has the clipboard open. To find out which window owns the clipboard, call the GetClipboardOwner function.

    After emptying the clipboard, the window places data on the clipboard in as many clipboard formats as possible, ordered from the most descriptive clipboard format to the least descriptive. For each format, the window calls the SetClipboardData function, specifying the format identifier and a global memory handle. The memory handle can be NULL, indicating that the window renders the data on request. For more information, see Delayed Rendering.

    Paste Operations

    To retrieve paste information from the clipboard, a window first determines the clipboard format to retrieve. Typically, a window enumerates the available clipboard formats by using the EnumClipboardFormats function and uses the first format it recognizes. This method selects the best available format according to the priority set when the data was placed on the clipboard.

    Alternatively, a window can use the GetPriorityClipboardFormat function. This function identifies the best available clipboard format according to a specified priority. A window that recognizes only one clipboard format can simply determine whether that format is available by using the IsClipboardFormatAvailable function.

    After determining the clipboard format to use, a window calls the GetClipboardData function. This function returns the handle to a global memory object containing data in the specified format. A window can briefly lock the memory object in order to examine or copy the data. However, a window should not free the object or leave it locked for a long period of time.

    For now, Silverlight Clipboard API only supports CF_UNICODETEXT format for copy/paste Unicode text to/from clipboard.

    Mac OS X uses Pasteboard Manager. It is documented at Mac Dev Center. Below excerpt (with APIs added) gives an overview:

    The copying application is responsible for placing copied or cut data onto the pasteboard:

    1. The user selects some data and invokes the Copy (or Cut) menu item.

    2. If the application doesn’t already have a reference to the Clipboard pasteboard, it creates one (PasteboardCreate).

    3. The application then takes ownership of the pasteboard and clears the current contents (PasteboardClear).

    4. The application assigns item IDs to the selected data.

    5. If any data is to be promised, the application must register a promise keeper callback function to supply the promised data (PasteboardSetPromiseKeeper).

    6. The application adds one or more flavors of each item to the pasteboard, including either the actual flavor data or a promise with each flavor (PasteboardPutItemFlavor).

    The receiving application has a slightly different set of tasks to handle the Paste action:

    1. When the application becomes active, it checks to see if the pasteboard has been modified (PasteboardSynchronize). If so, it obtains a listing of the flavors on the pasteboard. If there are any flavors the application supports, it can enable its Paste menu item.

    2. The user invokes the Paste menu item.

    3. The application requests the item (or items) on the pasteboard in the flavors that it supports (PasteboardGetItemCount, PasteboardGetItemIdentifier, PasteboardCopyItemFlavors, PasteboardCopyItemFlavorData).

    4. If the pasted data is to be stored as a file, the receiving application needs to set a paste location before requesting any flavor data. In any other case, the receiving application doesn’t need to worry about whether the paste data was promised or not.

    If the copying application’s promise keeper is called, the callback must do the following:

    • If the data is to be stored as a file, determine the paste location specified by the receiving application.

    • Generate or otherwise prepare the promised data for transfer.

    • If the promised data is not be stored as a file, add the flavor and data to the pasteboard. Otherwise, transfer the promised data to the specified file location.

    Some time later, when the application quits, or when it no longer needs the pasteboard, the application can release the pasteboard reference.

    As on Windows, Silverlight Clipboard API only uses kPasteboardClipboard and kUTTypeUTF16PlainText flavor to support copy/paste Unicode text to/from clipboard.

    Feedback

    We are excited to add clipboard support to Silverlight, and see all the important scenarios enabled by this simple API. I am interested in hearing your feedbacks, especially:

    • any security concerns over Silverlight clipboard API design and implementation
    • how important it is to add support for other data type/format, and in what priority order
    • how important it is to make the API extensible, like supporting IDataObject, allowing custom format/flavor and delayed rendering/promised data

    Thanks!

    -Ning

    Technorati Tags: ,

    Oct 21, 2009

    Silverlight Design Time: Toolkit October 2009 Release Update

    Overview

    Visual Studio 2010 Beta 2 is available now. For Silverlight developers, the most exciting news about VS2010 is that Silverlight designer will be in feature parity with WPF designer, and VS2010 will support multi-targeting for Silverlight development. Silverlight Toolkit team has been working closely with Cider team in providing the design time experience for Silverlight SDK and Toolkit controls. The design time for Silverlight 3 SDK controls has been released with SL3 SDK in August 2009, and is also chain installed by VS2010 Beta2. The design time for Toolkit controls, together with sources for both SDK and Toolkit controls, and their design time, samples, unit tests etc, are in Silverlight Toolkit October 2009 Release. We purposely made October 2009 release to be in sync with Visual Studio 2010 Beta 2 on Monday, 10/19/2009. This post demonstrates the new design time experiences for Silverlight controls in VS2010. 

    Install

    VS2010 installs side by side with VS2008. Multiple releases of Toolkit install side by side too. So it is perfectly safe to install VS2010 and Toolkit October 2009 release on your main machine. The only caveat is that if you have a pre August 2009 version of Silverlight 3 SDK installed, you will need to uninstall it first, before installing VS2010. You can install VS2010 Beta2 from http://msdn.microsoft.com/en-us/vstudio/dd582936.aspx, and Silverlight Toolkit from http://silverlight.codeplex.com.

    Walkthrough

    The October 2009 release is for Silverlight 3 only. It provides design time support for both VS2008 and VS2010, as well as Blend 3. Below walkthrough will be VS2010 only. Design time experience for VS2008 and Blend 3 are similar to July 2009 release. Please see my previous posts for design time experience with VS2008 and Blend3.

    • Create a new Silverlight Application project in VS2010, notice that:
      Create New Silverlight Application Project
      • the toolbox is populated with both SDK and Toolkit controls, with nice icons. If you have Blend3 installed before Toolkit, you may see a lot of Blend controls on the toolbox that are not supposed to. You can safely remove them by right click a control in the toolbox and select delete.
      • it is a real designer: both the design view and the properties window work!
    • double click TabControl in the toolbox will add a tabControl1. Notice that:
      Add Tab Control from Toolbox
      • A reference to System.Windows.Controls.dll is added, together with a xmlns definition: xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
      • tabControl1 is initialized with a tabItem1, which itself is initialized with a header and <Grid/> content. (via DefaultInitializer)
      • Property Items is selected in the Properties window (via DefaultPropertyAttribute)
      • Properties are categorized (via CategoryAttribute), and have tooltip (via DescriptionAttribute)
    • Double click tabControl1 will add an event handler for SelectionChanged event (via DefaultEventAttribute)
      Default Event
    • right click tabControl1, select Add Tab (via PrimarySelectionContextMenuProvider):
      VS10SL3TabAddTabCM
    • A new tabItem2 is added. Notice that:
      VS10SL3TabAddTabResult
      • tabItem2 is initialized with a <Grid/> content
      • tabItem2’s default property Header is highlighted. You can type into the text box next to it and change the object typed Header property directly. (via TypeConverterAttribute)
      • all properties have nice infotip
    • double click DatePicker on toolbox:
      VS10SL3DatePickerAdd
    • Now click tabItem1, notice that tabItem2’s content is hidden and tabItem1’s is shown:
      VS10SL3TabItemSelect
    • click Chart on toolbox:
      VS10SL3TabAddChartpng
      • a chart1 is added to the right place, initialized with sample data, and nicely rendered
      • default property Series is selected in the properties window
    • click the … button next to Series property to pop up the Collection Editor:
      VS10SL3ChartSeries
      • the Select item combobox is populated with the correct types (via NewItemTypesAttribute). The pink background for the icons are fixed now.
      • the Properties window for the series highlights the default property DependentValuePath, have all properties categorized (like the Data Visualization category), and you can modify the object typed Title property directly in the text box.
    • Create a simple data class with some simple properties, and add it as a data source, via Data |  Show Data Sources menu item: 
      VS10SL3Binding1
    • Drag MyData over tabItem1’s header and drop it :
      Data Binding
    • Just for fun, open the project in Blend 3, you will see very similar design time behaviors:
      VS10SL3Blend3

    Conclusion

    Above walkthrough is only a peek into all the design time features we have implemented for VS2010. I am very excited that VS2010 now provides a real designer for Silverlight, and I will continue enriching the design time experience for Silverlight in VS and Blend. Your feedback is welcome.

    I will write a series of posts explaining how those design time experience are implemented.

    Sep 29, 2009

    Silverlight Design Time: Toolkit July 2009 Release Update

    I have been very busy and haven’t post for a while, so this is a quick late post on Toolkit July 2009 Release. This release is the last Toolkit release for Silverlight 2: when a new version of Silverlight RTMs, we drop support for the previous version, so each Toolkit release needs to support at most two versions of Silverlight. As for design time feature updates, there have been a lot of improvements over March 2009 Release. I will use a simple walkthrough to highlight a few noticeable new features:

    • Install Silverlight 3, Blend 3 and Toolkit from http://silverlight.net/getstarted/
    • Open Blend 3, create a new Silverlight 3 Application project
    • Open Asset Library, notice few improvements:
      • the new Asset Library. See Unni’s blog The Blend 3 Asset Library for more info. 
      • the nicer icons and more informative infotip

    Blend 3 Asset Library

    • Add an Expander control, and set it as the new active container:
    Pin Active Container
    • Add a DatePicker to the Expander, notice that both the DatePicker and its Calendar drop down are shown, even though both Expander’s IsExpanded and DatePicker’s IsDropDownOpen are false.

    image

    • Select LayoutRoot so Expander and the nest DatePicker are no longer selected, notice that both are now collapsed.

    image

    Visual Studio ToolboxOpen the project in Visual Studio,notice that the Toolbox is populated with lots of controls from Silverlight SDK and Toolkit, with nice icons.

     

    So far, design time features for Silverlight are mostly exposed through Blend. This will change with next beta of Visual Studio 2010, which will come out soon, according to this Visual Studio Magazine article. Stay tuned!

    May 11, 2009

    Editing Model & Default Initializer for Silverlight Controls

    Introduction

    This is part of the series on design time feature implementation in Silverlight Toolkit. This post uses the Chart default initializer to illustrate how to implement default initializer for Silverlight controls, and explain the underlying editing model architecture.

    Experience

    If you install Silverlight 3 Toolkit in March 2009 Release, you can drag the Chart control from Blend Asset Library and drop it onto designer surface, and you have a chart nicely initialized and rendered:

    Chart default initializer

    You can read more about it in prior post Silverlight Toolkit Design Time Features: March 2009 Release Update.

    Architecture

    DefaultInitializer

    It is actually pretty simple to provide a default initializer for a Silverlight control:

    Below screenshot shows the implementation of DefaultInitializer abstract base class, and other classes in Microsoft.Windows.Design.Model namespace that will be discussed shortly:

    DefaultInitializer

    Initialization is done in InitializeDefaults override, and result is serialized into xaml. So the first step in implementing a default initializer is to define the desired xaml to be produced.

    Editing Model

    Once the result xaml is defined, I wish there is a higher level abstraction/method that would just take the xaml. But unfortunately we have to use a much lower level (thus more flexible and powerful) imperative API called editing model that consists of classes like ModelItem, ModelProperty, ModelEvent, ModelFactory and ModelService. The MSDN page Editing Model Architecture gives an basic overview:

    Your design-time implementation interacts with run-time controls though a programming interface called the editing model. The objects being designed are called editable objects.

    Your controls are defined in Extensible Application Markup Language (XAML). You update the XAML for your controls programmatically by using the editing model.

    Model, Wrapper, and View

    The editing model consists of three functional subunits: a model, a public wrapper that abstracts the model, and a view that represents the user interface (UI) of the model. The model and the view are separate, but the wrapper and model are closely related. The following illustration shows the relationship among the three subunits.

    Model, ModelItem, and View relationships

    The design environment uses the ModelItem type to communicate with the underlying model. All changes are made to the ModelItem wrappers, which affect the underlying model. This allows the model to be simple. The ModelItem wrappers handle complex designer features, such as transaction support, undo tracking, and change notifications.

    Below class diagram may help explain interactions among core classes of the editing model:

    Editing Model Class Diagram

    Use below xaml as an example:

    <UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="ModelTest.Page" Width="640" Height="480">

    <Grid x:Name="LayoutRoot" Background="White">
    <Button x:Name="Button">
    <Rectangle x:Name="Rectangle" />
    </Button>
    </Grid>
    </UserControl>
    • ModelItem: assume variable item is the ModelItem for the Button control above,
      • Name is persisted as x:Name attribute in xaml: item.Name = “Button” is persisted in xaml as x:Name = “Button”.
      • ItemType is the Type object of the underlying control, and decides the tag used in xaml: item.PropertyType == tyepof(Button), and the xaml tag is <Button />.
      • Properties is the collection of properties, wrapped in ModelProperty type, of the underlying control. For example: item[“ClickMode”] = ClickMode.Release will be persisted in xaml as ClickMode="Release".
      • Content represents the Content property defined in ContentControl (and inherited by its subclasses): item.Content is the ModelItem representing the Rectangle object.
      • Source: when a ModelItem represents an element that’s a property of another element, Source is the ModelProperty wrapper of that property. For example, item.Content.Value.Source == item.Content // the Rectangle.
      • Events represents the collection of events of the underlying control, wrapped in ModelEvent type. From my debugging experience, it is always null, so it seems Events property is not yet supported by Blend3 for Silverlight3 yet.
      • Parent is the the logic parent of the underlying control, wrapped in ModelItem type. ex: item.Parent is the ModelItem for Grid.
      • Root is the ModelItem wrapper for root visual, ex: item.Root represents the UserControl.
    • ModelProperty: assume variable prop is the ModelProperty for Button.Content, i.e. prop = item.Content,
      • Name is the name of the property of the underlying control. It is persisted in xaml as attribute name. ex: prop.Name == “Content”.
      • PropertyType is the Type object of the property of the underlying control this ModelProperty object represents. ex: prop.PropertyType = typeof(object).
      • AttachedOwnerType is the Type object of the control that first defines the property this ModelProperty object represents. ex: prop.AttachedOwnerType == typeof(ContentControl) // note: not Button.
      • Value is the value of the property of the underlying control, wrapped in ModelItem type. ex: prop.Value is the ModelItem representing the Rectangle object.
      • Parent is the control, wrapped in ModelItem type, of which the property belongs to. ex: prop.Parent == item.
    • ModelEvent: as mentioned above, item.Events is always null, so it doesn’t seem that ModelEvent is supported in Blend3 for Silverlight3 yet. But assume it works, and variable evt is the ModelEvent for Button.Click, i.e., evt = item.Events[“Click”],
      • Name is the name of the event. ex: evt.Name == “Click”.
      • EventType is the type of the event delegate, ex: evt.EventType == typeof(RoutedEventHandler).
      • Handlers is the string collection of event handlers, ex: evt.Handlers = new string[] { “Button_Click” } will be persisted as Click = “Button_Click”. Note: this is pure speculation, since ModelEvent isn’t yet supported, and I don’t know whether/when/how it will be supported for Silverlight.
      • Parent is the control, wrapped in ModelItem type, of which this event belongs to. ex: evt.Parent == item.

    Implementation

    The Chart default initializer class ChartDefaultInitializer is implemented in ChartDefaultInitializer.cs, and registered in ChartMetadata.cs. Both files are in Controls.DataVisualization.Toolkit.Design.csproj of Silverlight.Controls.Design.sln. Please read prior post Design Time Feature Implementation in Silverlight Toolkit for more information.

    Result XAML

    As the first step, define the result xaml to be produced by ChartDefaultInitializer:

       1: <Charting:Chart Title="Chart Title">
       2:     <Charting:Chart.DataContext>
       3:         <PointCollection>
       4:             <Point X="1" Y="10" />
       5:             <Point X="2" Y="20" />
       6:             <Point X="3" Y="30" />
       7:             <Point X="4" Y="40" />
       8:         </PointCollection>
       9:         <Charting:Chart.Series>
      10:             <Charting:ColumnSeries ItemsSource="{Binding}"
      11:                 DependentValuePath="X"
      12:                 IndependentValuePath="Y" />
      13:         </Charting:Chart.Series>
      14:     </Charting:Chart.DataContext>
      15: </Charting:Chart>

    Registration

    Done in ChartMetadata.cs with following code:

    b.AddCustomAttributes(new FeatureAttribute(typeof(ChartDefaultInitializer)));

    References

    See below screenshot:

    References

    Even though DefaultInitializer is defined in version 3.5 of Microsoft.Windows.Design.Interaction.dll (under %devenvdir%\PublicAssemblies, i.e. c:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PublicAssemblies on 32bit Windows), it is not supported by Blend2 or Visual Studio 2008 for Silverlight. It is supported by Blend3 and Visual Studio 2010, but they both switch to newer version of Microsoft.Windows.Design*.dll (3.7 for Blend 3 Preview, 4.0 for Blend 3 RTM and Visual Studio 2010), so we need to link against the newer version of MWDs. Please see prior post How to Write Silverlight Design Time for All Designers: Visual Studio 2008, Blend 2; Blend 3, and Visual Studio 2010 for more information.

    Please also notice that reference to Silverlight’s System.Windows.dll is aliased, and the PointCollection is specifically called out to be the Silverlight one, not WPF’s. Since WPF and Silverlight share a lot of classes in same namespaces, it is important that Silverlight types, not WPF’s, are used in creating ModelItem and ModelProperty in default initializer for Silverlight controls.

    Collections

    Please note in below screenshot that while all other property value can be set via ModelProperty.SetValue:

    ChartDefaultInitializer

    Chart.Series is of collection type (Collection<Series>), so its value has to be set by first creating a ModelItem via ModelFactory.CreateItem for the value, and then add the created ModelItem via ModelProperty.Collection.Add. Otherwise, even though the correct xaml may be generated, Blend won’t refresh to render the Chart control correctly, you have to reload the page to have it rendered correctly.

    ChartDefaultInitializer.cs

    // (c) Copyright Microsoft Corporation.
    // This source is subject to the Microsoft Public License (Ms-PL).
    // Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
    // All other rights reserved.

    extern alias Silverlight;
    using System.Windows.Controls.DataVisualization.Charting;
    using System.Windows.Controls.Design.Common;
    using Microsoft.Windows.Design.Metadata;
    using Microsoft.Windows.Design.Model;
    using SSW = Silverlight::System.Windows;
    using SSWD = Silverlight::System.Windows.Data;
    using SSWM = Silverlight::System.Windows.Media;

    namespace System.Windows.Controls.DataVisualization.Design
    {
    /// <summary>
    /// Default initializer for chart.
    /// </summary>
    internal class ChartDefaultInitializer : DefaultInitializer
    {
    /// <summary>
    /// Sets the default property values for chart.
    /// </summary>
    /// <param name="item">Chart ModelItem.</param>
    public override void InitializeDefaults(ModelItem item)
    {
    string propertyName;

    // <Charting:Chart Title="Chart Title">
    propertyName = Extensions.GetMemberName<Chart>(x => x.Title);
    item.Properties[propertyName].SetValue(Properties.Resources.ChartTitle);

    // <Charting:Chart.DataContext>
    // <PointCollection>
    // <Point X="1" Y="10" />
    // <Point X="2" Y="20" />
    // <Point X="3" Y="30" />
    // <Point X="4" Y="40" />
    // </PointCollection>
    // </Charting:Chart.DataContext>

    SSWM::PointCollection defaultItemsSource = new SSWM::PointCollection();
    for (int i = 1; i <= 4; i++)
    {
    defaultItemsSource.Add(new SSW::Point(i, 10 * i));
    }

    propertyName = Extensions.GetMemberName<Chart>(x => x.DataContext);
    item.Properties[propertyName].SetValue(defaultItemsSource);

    // <Charting:Chart.Series>
    // <Charting:ColumnSeries ItemsSource="{Binding}"
    // DependentValuePath="X"
    // IndependentValuePath="Y" />
    // </Charting:Chart.Series>

    ModelItem columnSeries = ModelFactory.CreateItem(item.Context, typeof(ColumnSeries));
    propertyName = Extensions.GetMemberName<ColumnSeries>(x => x.ItemsSource);
    columnSeries.Properties[propertyName].SetValue(ModelFactory.CreateItem(columnSeries.Context, typeof(SSWD::Binding)));
    propertyName = Extensions.GetMemberName<ColumnSeries>(x => x.DependentValuePath);
    columnSeries.Properties[propertyName].SetValue("X");
    propertyName = Extensions.GetMemberName<ColumnSeries>(x => x.IndependentValuePath);
    columnSeries.Properties[propertyName].SetValue("Y");

    propertyName = Extensions.GetMemberName<Chart>(x => x.Series);
    item.Properties[propertyName].Collection.Add(columnSeries);
    }
    }
    }