Jaime Rodriguez
On Windows Store apps, Windows Phone, HTML and XAML

  • Jaime Rodriguez

    Windows phone capabilities security model

    • 0 Comments

    Today, Microsoft released the Windows Phone Developer Tools CTP- April Refresh.  You can find most of the details on the new features for this release at the Windows Phone developer blog.

    One of these new features is the capabilities-driven security model.

    What are capabilities?
    A Capability is defined as a resource for which privacy, security, cost or business concerns exist.  Examples of capabilities include GPS, camera, microphone, SMS or sensors. 

    As of April Refresh, the following capabilities have been disclosed:

    Capability Id/Name Description
    ID_CAP_NETWORKING Apps with access to network services. Disclosed because services could incur cost when roaming.
    ID_CAP_LOCATION Apps with access to location services.
    ID_CAP_MICROPHONE Apps that access the microphone; can record without visual indication that recording is taking place.
    ID_CAP_MEDIALIB Apps that can access media library.
    ID_CAP_GAMERSERVICES Apps that interact with XBOX live APIs.  Disclosed due to privacy since data is shared with XBOX.
    ID_CAP_PHONEDIALER Apps that place phone calls; possibly without visual indication to end-user.
    ID_CAP_PUSH_NOTIFICATION Apps can receive push notifications from internet service; disclosed because services could incur cost when roaming.
    ID_CAP_WEBBROWSERCOMPONENT Apps that will use the webbrowser component; if script is turned on, this can have security risks.

    *Note: I am only listing the ones publicly disclosed; there are more capabilities, but some are specific to mobile operators and OEMs, others I have not seen publicly disclosed so I am not comfortable sharing.

    Why do we have/need capabilities?
    Windows Phone leverages capabilities to:

    • Decrease the attack surface.  Capabilities are used by the package loader at install-time to create a security chamber within which the application will execute. This chamber is created once at install-time and used from there-on.
    • Ensure proper disclosure happens to the end-user. Each application discloses its capabilities.
      Pending the capabilities used (and maybe the marketplace) there will be several types of disclosures:
      • Disclosure on the application details page in the marketplace  - is the least
      • Disclosure with a prompt at purchase time, for those capabilities that have legal requirements
      • Disclosure with-in the app, when a capability is about to be used.

    As a developer, how do I code or prepare for capabilities?
    It is very simple, your application includes the list of capabilities it needs in WMAppManifest.xml.
    Starting with the April CTP Refresh, when you create a new Windows Phone Application,  the tools automatically include the following capabilities declaration in the WMAppManifest.xml file:

    <App xmlns="" … >
          <Capabilities>
         <Capability Name="ID_CAP_NETWORKING" />
         <Capability Name="ID_CAP_LOCATION" />
         <Capability Name="ID_CAP_SENSORS" />
         <Capability Name="ID_CAP_MICROPHONE" />
         <Capability Name="ID_CAP_MEDIALIB" />
         <Capability Name="ID_CAP_GAMERSERVICES" />
         <Capability Name="ID_CAP_PHONEDIALER" />
         <Capability Name="ID_CAP_PUSH_NOTIFICATION" />
         <Capability Name="ID_CAP_WEBBROWSERCOMPONENT" />
       </Capabilities>

    This manifest is requesting all capabilities.  If you do not need a specific capability, you can just remove or comment out the capability within the manifest.

    If you do not request a capability in your manifest, and try to use a feature restricted by this capability, you will get an
    UnauthorizedAccessException  with an “Access denied” message. The exception will not happen until you try to use the capability. So your app will load and run fine, up to the point when you try to use the capability and then kaboom! busted!

    There is no developer API to check if you have a capability. The assumption is if your application is installed, you got the capabilities you requested, and you should party. If you did not request the right ones, you will then meet the UnauthorizedAccessException we met in the last paragraph.

     


    Any extra tips?
    For now, as you are developing and likely don’t have a phone, I recommend you stick to the default capabilities (all).  There are still some scenarios that require a capability and is not obvious from the descriptions I have seen. Here is the ones I have seen so far: 

    Capability class or namespace that requires it
    ID_CAP_MEDIALIB MediaStreamSource,
    Microsoft.Devices.Radio,
    Microsoft.Xna.Framework.Media.MediaLibrary and MediaSource,
    Microsoft.Devices.MediaHistory
    ID_CAP_NETWORKING System.Net,
    Microsoft.Xna.Framework.GamerServices.GamerServicesComponent,
    WebBrowser class,
    Smooth Streaming Media Element (SSME)
    ID_CAP_PUSH_NOTIFICATION
    ID_CAP_SENSORS Microsoft.Devices.Sensors
    ID_CAP_MICROPHONE Microsoft.Xna.Framework.Audio.Microphone
    ID_CAP_PHONEDIALER Microsoft.Phone.Tasks
    ID_CAP_PUSH_NOTIFICATION Microsoft.Phone.Notification
    ID_CAP_WEBBROWSERCOMPONENT WebBrowser class
    ID_CAP_LOCATION System.Device.Location

     

     

    Stay tuned for more.  Please let me know via comments or email if you find one I missed.

  • Jaime Rodriguez

    Theming in Windows Phone

    • 1 Comments

    A theme is a visual definition of the look & feel for common controls in an Operating System. 
    Themes are usually end-user selectable, changing the theme at the OS level, impacts the look & feel of running applications that are ‘theme aware’.  As an example, on Windows Vista and Windows 7, a popular/desired theme is the Aero theme.

    Windows Phone supports theming. Here is a screenshot of the themes in action in Windows Phone.  

        image         image       image

    This is the exact same app. No code changes, and no recompile. I switched the OS themes to get the different look and feel.

    Since theming is new to Silverlight,  I went under the hood for the implementation details, below are my findings (when dissecting the MIX Preview release). 
    Note:  This is pre-released preview software, it will definitely change [I will point a few coming changes, and I am sure there will be more than I know about now] .

    Default

    Details on how end-users will configure themes:

    • The pre-defined themes are a combination of a background + accents colors. 
      • You get a Dark or a Light Background.
      • The accent colors can be Orange, Blue, Red, Green
        [Figure to the right of this paragraph shows the themes configuration screen].
    • OS themes are not extensible; you can’t create and install your own theme.  You can install your own application skin; a skin would change the look and feel for just your app; where a theme can affect all apps.
    • Users can select the active theme on the OS [or the emulator] from Settings –> Themes.
      [The emulator does not persist the theme selection across emulator runs, but if you change the theme it is persisted in memory, allowing you to use that theme for the duration of your emulator session]

    Developer/implementation details: 

    • As expected (for Silverlight applications), theming is implemented using resources and resource dictionaries.  
    • The way the themes are implemented is this:
      • There are pre-defined names for the resources in a theme. Most of the names follow this format:  Phone<Feature/Functionality><Type>  for example:  PhoneBackgroundColor or  PhoneAccentBrush.
      • You can take a peek at the resources in a theme from the resource dictionaries at C:\Program Files (x86)\Microsoft SDKs\WindowsPhone\v7.0\Design  (or just program files if running 32-bit OS).
      • These theme resources are injected into the run-time at application startup.  
        1. The resources are resolved as if they were at  a higher level than Application level Resources.
          If you are familiar with Silverlight or WPF, the {StaticResource} markup extension look-ups are resolved bottom-up, where a UIElement first looks for a desired resource in its Resources collection; if the resource is not there it will query up the visual tree on its Parent’s resources collection (and iteratively the parent’s parent, ,all the way up to the root of the tree.  If the resource is not found, the resource resolution logic then looks in the Application.Resources collection.   
          For Windows Phone, if the resource is not found in the standard resolution above, it will then query the themed resources collection (inserted by the OS) to try to resolve it. 
          Note: see known issues below for known bugs on resource resolution at MIX release]
        2. The resources are injected before Application.InitializeComponent is called. 
          This means, if you insert a resource into App.xaml, that references a Theme resource, you will be fine..   
          At the same time, it is nice that they live in its own private collection
        3. There is some magic on where these are stored. You cant’ see them at run-time (there is no exposed object that shows them), but you can reference and query for them.  See Figure 2 below, the debugger tells me there is no resources on the Page or Application Resources collections, but when I query them, they are there. 
          image
          Personally, I am still undecided with theme resources resolving at Page level (via this.Resources). 
          I think this has implications with regards for those of us that have our equivalent to WPF’s TryFindResource, but not a huge deal since these are supposed to be Theme resources. Again, just don’t use the names in the theme.
    • Since you are running Silverlight applications (so only StaticResources) the expectation is that theming changes are picked up once per application at start-up.   There is no system-wide event or notification that tells you that the current active theme has changed.  [This should not be an issue; but wanted to save you from looking for the event]
    • There is no API to detect the active theme. As a workaround, you can peek into the resources (e.g. look at PhoneBackgroundColor, to know if you are running the Dark or Light theme and look at PhoneAccentColor to know the accent). 

    A known issues at MIX release:

    There is a bug in the MIX preview release that makes resource resolution behave different from what I described above.  The bug is that {StaticResource}  lookups are looking at the “themed resources” collection  first instead of looking at  application resources first.  This is a bug and will be fixed in later builds.

    Note that this is not a big issue, you would only see this issue if your themed resources, and your application resources do not match.  There is two scenarios when this can happen:

      1. If you try to override the theme by inserting your own resources into App.Resources with the same names.  I have to recommend that you do not do that. If you don’t want theming it is safer to create custom templates and styles to get your look & feel right (and bullet proof).
      2. If your design-time resources – inserted by VS2010 tooling into App.xaml  - are not matching the theme running on the OS.  This is a variation of #1 above, but with this one, the developer had no intention to override the resources, therefore I had to highlight it separately.  It also had me all confused given it behaves different from SL on desktop and WPF.

        Here is a detailed explanation on the resources in App.xaml:
        The VS 2010 tooling inserts the equivalent of the DarkBlue theme into App.xaml, in the resources collection. 
        This is handy for design-time and it works at run-time due to bug above.   That said,  the resources in App.xaml are not required at run-time.  You can remove most of the resources in App.xaml and check that still your works.   You can see this in my sample code attached to this post.

        The only two resources from App.xaml that you should not remove are the two styles: PhoneTextpageTitle1Style and PhoneTextPageTitle2Style.   These two styles are not themed resources and are referenced by the default PhoneApplicationPage template created by Visual Studio.  What I did for my app was move these resources back to the Page resources collection, ending up an empty App.Resources collection, and two styles in the MainPage resources collection.

    Sample code is at http://learningwindowsphone.com/samples/LearningWindowsPhone.ThemesAtMIX.zip  

    That is it all you should need to know to get going with themes. Now, you can plan for your Windows Phone application to be theme-aware.

  • Jaime Rodriguez

    A JOURNEY INTO SILVERLIGHT ON WINDOWS PHONE -VIA Learning WIndows PHone Programming

    • 0 Comments

    If you are a Silverlight  developer take a quick “Journey into Siverlight on Windows Phonecoverby checking out the free preview of Chapter 6 on the “Learning Windows Phone Programming” book by  my colleague Yochay Kiriaty and yours truly.   

    In this quick read, and you will get a high level glimpse at the the Silverlight stack on Windows Phone and understand the reasons for the few small tweaks..   Mike Harsh said at MIX “if you are a Silverlight developer, congrats you just graduated to Windows Phone developer”..  I am changing that one to “after you read this chapter you will have graduated as a Windows Phone developer” :)

    You can also download code samples for this chapter from the code section on the Learning Windows Phone site.  This site is a work in progress (our friend who will do the design is on vacation, bear with us).  Check the site often as we will soon add the ‘engage’ capability..

    Feedback on both the chapter and the site are welcome and appreciated! Try the contact page on the site.  Also, in case you missed it, we have another free chapter for “Building your first Windows Phone application”.

    If you like the chapter, please tweet it, or share it. we want others to enjoy it and to share feedback on it!
  • Jaime Rodriguez

    Three upcoming WPF trainings

    • 6 Comments

    Last year, Karl and I had a blast on our WPF for Line of Business tour.  It was so cool to meet all these people doing or planning to do WPF.  This year, budget is tighter, so no big tour.. but still plenty of WPF and Windows 7 training coming to a city near you..  
    Here are the details:

    April 15,  London, UKClient Development with Visual Studio 2010, .NET Framework 4 & Windows 7 at Techdays  UK Mike Taulty, Ian Griffiths, Paul Foster, and others will do a “Client Day” at Microsoft Techdays, UK.
    This is an all-day Lap Around Windows 7, .NET 4, and any thing you want to ask these guys.  Mike,Ian and Paul know everything about WPF, Silverlight, .NET and predicting the stock market. Don’t miss out on their tips.  Register here.

    April 28,29  - Redmond, WA   -- WPF For Line-Of-Business, Reloaded.
    Karl Shifflett and I will do the same two-day version of the WPF for Line Of Business training we did last year.   This is a two-day deep dive into WPF:  Day one is fundamentals, Day two has an MVVM focus.   

    This is FREE, you get breakfast, lunch and afternoon snack.  Register here. 
    First-come, First serve, limited capacity. You should hurry, but please register only if you are committed to attend.

    April 30, Redmond WA – Building Windows 7 Applications with Windows Presentation Foundation and .NET 4.
    Karl, me, and a few members of the WPF team will recap the new WPF features in .NET 4, and how to use these features to create applications that take advantage of Windows 7.

    Expect to hear about client profile, multi-touch, taskbar, all the new graphics enhancements. etc.

    This is FREE, you get breakfast, lunch and afternoon snack.  Register here. 
    First-come, First serve, limited capacity. You should hurry, but please register only if you are committed to attend.

    If you can’t make these dates or these cities. Don’t worry. The Redmond trainings will be recorded and published online. 
    That said, join us if you can.  You will learn much more in person than watching the videos. We would love to have you.

    Stay tuned for detailed agenda.  Register as soon as possible if you want a seat.

    [PS—If you have a blog, or you participate in any other form of social sharing, please spread the word.
    We thank you in advance!]

    Update 3/24 --  We will only do the locations above. Again, Redmond will be recorded and posted online. 
    As much as we would love to do a tour, this year it simply was not possible; let's try online and see if we can make it work; it could be a way to reach more people (even if not 1:1)

  • Jaime Rodriguez

    I am back..

    • 1 Comments

    I hear that I am not supposed to do the “sorry, I got busy..” blog post… but it has been long enough that I do feel I owe you a “catching up” post…

    Where did I go?  nowhere.   I am still in the same team, at Microsoft. Doing the same gig (working with big customers on the coolest apps that use any .NET client technology (including WPF, Silverlight, and a new addition Windows Phone)..

    Why did not you call, email, or blog?   At first, I was a bit too busy with events like PDC, CES and MIX preparation… 
    After that, I was a bit consumed by Windows Phone but could not blog about it.  i was also letting technology and demand take its course.   You will hear more about it as I go.

    How is the family?  wife and kids are good.  We moved (a whole 4 miles distance, but new school district).  Samuel just finished basketball season, we are moving on to T-ball…  Sophia is at a wonderful fun/loving age (almost 4); I am enjoying every minute since I already know time flies when your kids are young.

    Now that you are back; are you going to blog more frequently and stick with it?
    I will try!  Can’t guarantee it, but will give it a second run… I am super excited about what is coming down the pipeline at Microsoft and have lots of opinions and tips to share around that…

    Can we still email you or contact you via blog contact page? 
    Yes,  please do..    I would love ideas for topics to blog on, or questions on old posts..  stay tuned and you will hear I am adding technologies to my repertoire..

    Thanks for reading [for those that stuck around :)]

  • Jaime Rodriguez

    Introduction to WPF 4 Multitouch

    • 6 Comments

    This tutorial recaps the multitouch features in WPF 4, as of the Beta 2 release.
    I also included two basic samples to get you jumpstarted with working code:

    A Multitouch Backgrounder

    Multitouch is simply an abstraction from the OS (or a platform) that routes touch input to an application. 
    The OS exposes multitouch input with different levels of control and/or detail.  For example, Windows 7 exposes multitouch data in three modes:

    • Raw touch provides access to all touch messages. Aggregation or interpretation of the messages is left to the application. This level of access is useful for programs that require raw access to all the primitives possibly for some custom interpretation and handling of the messages. For example Corel Paint It Touch and Windows 7 Paint require this level of control to implement drawing. Other possible consumers for this level of detail are custom control or platform vendors.
    • Gestures is a very convenient abstraction from raw-touch.
      The platform interprets all the lower level events and translates them into pre-defined gestures, then notifies the application that a gesture has occurred.  The most common gestures are pan, zoom, rotate, and tap.
      Gestures offers a very easy programming model, but it has a limitation: gestures engines tend to handle only one gesture at a time ( for example, rotate or zoom, but not a rotate with zoom).  
    • Manipulation and inertia.   
      Manipulation is a superset of gestures; any thing you can do with gestures, you can do with manipulations, but you gain greater granularity and flexibility.  Of course, the trade-off is that manipulation is a pinch harder to program than gestures, but don’t worry, both are straight forward.
      Inertia is an extension to manipulation that adds physics support to make all of your manipulations smooth and realistic.

    If you are not familiar with multitouch, I recommend these articles on multitouch in Windows 7:

    Now that you are a touch expert,  we can simply focus on explaining WPF’s support.

    Multitouch in WPF 4

    WPF 4 includes support for raw touch and manipulation (with some inertia support).  This support extends throughout the platform; UIElement, UIElement3D, and ContentElement have all been tweaked to support raw-touch and manipulation.

    Post beta2, WPF 4 will also support touch in some of the controls (for example, ScrollViewer). The list of controls and level of support is not yet finalized, so don’t hold it against me; I will update this post as soon as I get details.

     

    Approach #1: Raw-touch in WPF 4

    Again, raw multitouch support begins at UIElement, UIElement3D and ContentElement.
    All of these types now support a TouchDown, TouchUp, TouchMove, TouchEnter and TouchLeave event.
    Each of these events have a corresponding routed event and a tunneling (Preview) event. 

    • public static readonly RoutedEvent TouchDownEvent;
    • public static readonly RoutedEvent TouchEnterEvent;
    • public static readonly RoutedEvent TouchLeaveEvent;
    • public static readonly RoutedEvent TouchMoveEvent;
    • public static readonly RoutedEvent TouchUpEvent;

     

    If you drill down through these events, you will find they all have a TouchEventArgs parameter that holds a TouchDevice member and can get you a TouchPoint.  The TouchPoint is the meaningful data since it tells you whether it was a Up,Down, or Move TouchAction, and it tells you the Position where the touch happened.

    I have included a class diagram below; the names are pretty descriptive.

    Touch

     

    Handling raw touch in WPF is really as simple as listening for these events and reacting to the points and the actions. 
    Unlike Manipulation where you do have to opt-in by setting the IsManipulationEnabled property to true,  event notifications for raw touch are available without an explicit opt-in


    A sample application for raw touch

    Of course, for raw touch I had to create the canonical helloMT drawing pad.   

    Disclaimer: I took the code written by Sela to demonstrate the .NET wrappers for Windows 7 multitouch and simply ported it to WPF 4.  Taking their apps and porting them to WPF 4 was about a 15 minute exercise.

    Download the source code.  

    When running the app, simply apply multiple fingers through the window to have the drawing pad draw strokes that follow your fingers’ movements.


     

    Approach #2: Manipulation in WPF 4

    Manipulation in WPF 4 is an opt-in behavior.  There is a simple process to handle manipulation events in any WPF element:

    1. Set IsManipulationEnabled=true on the element you are touch enabling. You can do this from XAML or from code. 

      <
      Image x:Name="image"Width="200"IsManipulationEnabled="True" Source="Windows7.png">
    2. [Optional] Subscribe to ManipulationStarting and set your ContainerElement. 
      The ContainerElement is the UI element to which all manipulation calculations and events are relative. If you do not set a ContainerElement, the UI element that is firing the event will be used. This works well for Zoom/Scale, but for all Translate or Rotate manipulations you should set a ContainerElement, or else the UI will flicker and be jumpy. This is not a UI glitch, it happens because a single manipulation will fire multiple deltas, so you are recording movements relative to the UI element that is being moved. Not cool!

      In ManipulationStarting, you can also set your ManipulationMode to control the manipulations you are allowing. You can select from All | None | Rotate | Translate | Scale | TranslateX | TranslateY. If you don’t override it, the default is All.

      Finally, if you want to do single hand rotations, you can set a Pivot that your UI element will rotate around.
       void image_ManipulationStarting(object sender, ManipulationStartingEventArgs e)
       {   
              //canvas is the parent of the image starting the manipulation;
              //Container does not have to be parent, but that is the most common scenario
               e.ManipulationContainer = canvas; 
              // you could set the mode here too 
              // e.Mode = ManipulationModes.All;             
       }
    3. Subscribe to the ManipulationDelta event in the UI Element (or an element higher in the Visual tree, since the event is routed).  ManipulationDelta is where all the action happens.  I have included a “default” implementation below, with good commenting.
      void image_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
      {
          //this just gets the source. 
          // I cast it to FE because I wanted to use ActualWidth for Center. You could try RenderSize as alternate
          var element = e.Source as FrameworkElement; 
          if ( element != null ) 
          { 
              //e.DeltaManipulation has the changes 
              // Scale is a delta multiplier; 1.0 is last size,  (so 1.1 == scale 10%, 0.8 = shrink 20%) 
              // Rotate = Rotation, in degrees
              // Pan = Translation, == Translate offset, in Device Independent Pixels 
               
              var deltaManipulation = e.DeltaManipulation; 
              var matrix  = ((MatrixTransform)element.RenderTransform).Matrix;            
              // find the old center; arguaby this could be cached 
              Point center =  new Point ( element.ActualWidth/2, element.ActualHeight/2) ;
              // transform it to take into account transforms from previous manipulations 
              center = matrix.Transform(center); 
              //this will be a Zoom. 
              matrix.ScaleAt(deltaManipulation.Scale.X, deltaManipulation.Scale.Y, center.X, center.Y); 
              // Rotation 
              matrix.RotateAt(e.DeltaManipulation.Rotation, center.X, center.Y);             
              //Translation (pan) 
              matrix.Translate(e.DeltaManipulation.Translation.X, e.DeltaManipulation.Translation.Y);
      
              ((MatrixTransform)element.RenderTransform).Matrix = matrix; 
      
              e.Handled = true;
          }
      }


    That is how simple manipulation is. All the raw-touch data, translated into these simple Delta Matrixes!  

    Enhancing Manipulation with Inertia

    Inertia adds physics to a manipulation to make it feel more natural.  As expected, it works on all UI elements that support manipulation. The way to think of inertia is that it carries through the physical momentum of a manipulation. For example, if you are implementing a translation manipulation that is moving an image across the X-axis, inertia will continue the manipulation a bit longer than the actual manipulation contact and it would decelerate at a speed you define, simulating the momentum and the friction to stop the translation.

    To add support for inertia, we simply update our old code and listen to a new event and then add code to handle inertia on our manipulation Delta.

    1. Subscribe to ManipulationInertiaStarting. 
      This event is similar to ManipulationStarting, it gets called at the beginning of each individual manipulation. In the event handler we append parameters to the Manipulation. For inertia, the interesting properties include:
      • ExpansionBehavior – decelerates at DIPs per squared millisecond . 
      • TranslationBehavior  - decelerates at DIPs per millisecond.
      • RotationBehavior - decelerates at degrees per millisecond
      • InitialVelocities is read-only; it gives you the velocities calculated from the previous stage of the manipulation. You can use these values to calculate your own behaviors. 

        image 

        Here is the code to add our desired behaviors for inertia:

        void canvas_ManipulationInertiaStarting(object sender, ManipulationInertiaStartingEventArgs e)
        {                
                // Decrease the velocity of the Rectangle's movement by 
                // 10 inches per second every second.
                // (10 inches * 96 DIPS per inch / 1000ms^2)
                e.TranslationBehavior = new InertiaTranslationBehavior()
                {
                    InitialVelocity = e.InitialVelocities.LinearVelocity,
                    DesiredDeceleration = 10.0 * 96.0 / (1000.0 * 1000.0)
                };
        
                // Decrease the velocity of the Rectangle's resizing by 
                // 0.1 inches per second every second.
                // (0.1 inches * 96 DIPS per inch / (1000ms^2)
                e.ExpansionBehavior = new InertiaExpansionBehavior()
                {
                    InitialVelocity = e.InitialVelocities.ExpansionVelocity,
                    DesiredDeceleration = 0.1 * 96 / 1000.0 * 1000.0
                };
        
                // Decrease the velocity of the Rectangle's rotation rate by 
                // 2 rotations per second every second.
                // (2 * 360 degrees / (1000ms^2)
                e.RotationBehavior = new InertiaRotationBehavior()
                {
                    InitialVelocity = e.InitialVelocities.AngularVelocity,
                    DesiredDeceleration = 720 / (1000.0 * 1000.0)
                };
                e.Handled = true;                  
        }
      • You may notice I did not override the ManipulationContainer. This is not required; it will reuse the ManipulationContainer we set during the ManipulationStarting event.

    2. [Optional] Now, we could add code at our ManipulationDelta event handler for inertia. 
      This is optional, if you run the code at this point, inertia is already working, but you will notice there is no boundaries (the images fly off the screen).  So, just as an example, I will add code to handle the boundaries and stop the inertia when we reach the boundaries.
      void image_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
      {
          // …. this is the same code as above, in our manipulation delta.. 
      ((MatrixTransform)element.RenderTransform).Matrix = matrix; e.Handled = true; // Here is the new code.
      // We are only checking boundaries during inertia in real world, we would check all the time
      if (e.IsInertial) { Rect containingRect = new Rect(((FrameworkElement)e.ManipulationContainer).RenderSize); Rect shapeBounds = element.RenderTransform.TransformBounds(new Rect(element.RenderSize)); // Check if the element is completely in the window. // If it is not and intertia is occurring, stop the manipulation. if (e.IsInertial && !containingRect.Contains(shapeBounds)) { //Report that we have gone over our boundary e.ReportBoundaryFeedback(e.DeltaManipulation); // comment out this line to see the Window 'shake' or 'bounce' // similar to Win32 Windows when they reach a boundary; this comes for free in .NET 4 e.Complete(); } } } }


      That is it. Our image viewer now has inertia support, and we have full control on the deceleration, rotation ratios, etc.
    A sample application for Manipulation and Inertia:

    Image Viewer. Manipulation
    This sample uses the code above to manipulate the images on the canvas. 

    Download the source code

    The viewer supports scaling, translating, and rotating the images, using multitouch gestures. There is also inertia support as you execute any manipulation.

     

     

     

     

    Mixing and matching approaches:

    In WPF 4 raw-touch and manipulation are not mutually exclusive –this is different from Win32. 
    You can enable both raw touch and manipulation at the same time on any UI Element.  

    The table below explains how logic is handled for scenarios with different options enabled.

    Manipulations Enabled

    TouchDown is Handled

    GotTouchCapture is Handled

    User Logic

    WPF Logic

    None

    No

    No

    None

    Promoted to Mouse

    None

    Yes

    No

    Handled as Touch by user

    None

    None

    Yes

    Yes

    Handled as Touch by user

    None

    Enabled

    No

    No

    None

    1. Handled by Manipulation logic, TouchDevice is Captured,

    2. Manipulation logic will handle GotTouchCapture event and manipulation events will be reported

    Enabled

    Yes

    No

    Handled as Touch by user. User has to explicitly capture the touch device.

    Manipulation logic will handle GotTouchCapture event and manipulation events will be reported

    Enabled

    Yes

    Yes

    1. Handled as Touch by User.

    2. User has to explicity capture the touch device.

    3. GotCapture handled by user, user has to explicitly AddManipulator to invoke manipulation

    None

     

    Summary

    This tutorial provided a basic introduction to multitouch in WPF. As you have seen, WPF supports both raw-touch and manipulation (with inertia) for all WPF UI elements. 

    Using WPF’s new touch support, you can accomplish quite a bit with just a few lines of code. The support compliments and integrates quite well with the platform.

  • Jaime Rodriguez

    WPF discussions, 091101

    • 0 Comments

    As usual, raw, unedited, useful info from the Microsoft’s internal WPF discussions lists.


    Subject: All keys don't work in a WPF window when it is calling from a WinForm project.
    We had a big project developed in WinForm. Now I'm adding a new window to the project using WPF. The WPF window is now part of the project, i.e. it is not a separate project or dll. What happened now is any control that is supposed to accept keyboard inputs, such as textbox, does not respond to my keyboard input. The window only responds to mouse.

    Answer:
    You must use call the
    EnableModelessKeyboardInterop method for keyboard to work.


    Subject: Precision on WPF animations
    This question was from a partner. they have some synchronization issue between their own animation and WPF animation. The difference of ~0.2 can happen because WPF animation precision depends on rendering timing, doesn’t it ?

    Answer:
    That's right - we do a number of things to sync with rendering. 
    Time only "changes" at the start of a render pass, which is scheduled differently based on a number of factors (Desktop Window Manager present and enabled? Monitor refresh rate, desired framerate for animations, etc), and then too the time chosen is actually "in the future" a bit because we're trying to produce a set of changes that will be correct when they hit the screen.  To do this, we estimate the future presentation time for a given UI thread's render pass.  My guess is that this is what they're seeing in this case


    Subject:  Using Blend Behavior in Style?
    Why am I getting an error when setting a Behavior in a style. Isn’t Blend Interaction an AttachedProperty?

    Answer:
    Blend’s behaviors are an attached property, but publicly they are not exposed as a DP- you can do attached properties that are not DP’s by having just the static GetProperty/SetProperty.
    We use this syntax to keep the behavior syntax smaller- by not using a real DP here we were able to default the collection to having a value and remove 2 lines of XAML. If this were a real DP then you’d have to add the collection to the XAML as well:

    <Button>

      <i:Interaction.Behaviors>

    <i:BehaviorCollection>

          <s:SimpleBehavior/>

    </i:BehaviorCollection>

      </i:Interaction.Behaviors>

    </Button>

    In addition behaviors cannot be used inside of styles; the core issue is that we intentionally made behaviors not sharable- you can’t apply the same behavior to multiple elements. The reason is that if you use the WPF animation API as an example that it adds a ton of complexity to make the types sharable and it really detracts from the level of simplicity that we were looking for in Behaviors.

    In WPF, everything applied through a style is shared  across each element that it’s applied to. To get around this in early prototypes I used a trick with Freezables and the CoerceValueCallback to clone the behaviors every time they’re applied to an element and are already applied to something else, but none of this is present in SL and it can lead to some unexpected runtime behavior.


    Subject: Best Match for ICO in WPF?
    Is there a built-in way in the WPF 4.0 imaging classes to get a “best match” for a multi-frame ICO?

    Answer:
    We don’t have any automatic selection logic. You can iterate over all of the frames and find the one you want based upon each frame’s properties. You should be able to get them all from a frame by doing frame.Decoder.Frames. Alternatively, you can just do BitmapDecoder.Create and read the frames that way rather than indirectly through BitmapFrame.Create.
    Note: pre-Win7 WIC does not support Vista’s PNG icon frames. If you hit a PNG frame you will get an exception on Vista and XP.


    Subject: Binding and Custom Type Descriptors
    In WPF we’re binding an object that has a custom type descriptor and are wondering if there is a way to get around a couple issues:

    1. Is there a way to get WPF to listen to these changes given that WPF does not appear to subscribe to change events via PropertyDescriptor.AddValueChanged?
    It appears that WPF will bind to the properties offered through the type descriptor, but WPF does not monitor that type descriptor for value changes.    It does appear to listen to INotifyPropertyChanged events, but this is not that useful if we are extending and object with custom properties.

    2. Is there a way to have WPF bypass ICustomTypeDescriptor.GetProperties() when setting up a binding? In this case, custom types may hide the thing we actually want to bind to, so it would be useful to force WPF not to use the custom descriptor during binding.

    Answer:
    1. WPF will listen to ValueChanged if the object doesn’t implement INotifyPropertyChanged.  If both are available we only listen to INPC, to avoid duplicate notifications.  There are objects that expose both – chiefly ADO.Net’s DataRowView – so it’s a real issue.   If you have appropriate access, you can get the object to raise the PropertyChanged event with a property name for your custom property.  But if it’s not your object (and its OnPropertyChanged method is private), you’re out of luck.

    2. No.  We actually call TypeDescriptor.GetProperties(item), which in turn calls ICTD.GetProperties, so it’s out of our hands.  Usually people want the custom descriptor to override the native one;  we don’t have any way to ask for the other way around.  (I’m curious what your scenario is, though.  This is the first time someone’s asked for this.)


    Subject: Binding to dictionary with multiple indexers
    If I add a second indexer to a collection class, it will no longer bind to WPF FrameworkElement such that its index path can be referenced.
    The following works fine on regular collection, But I add a second indexer, or if the collection is keyed, the binding no longer works:

      Path=[0].

    Answer:
    Your two indexers have different signatures, probably something like

                    public object this[int index] { …}

                    public object this[string s] {…}

    The property path is declared in XAML, where everything is a string.  So when you say “Path=[0]”, WPF has to decide whether you mean the first indexer with argument (int)0, or the second indexer with argument (string)”0”.   There’s nothing in the XAML to indicate which one you mean, so I think we choose the line of least resistance and pick the second indexer – it requires no type conversion.

    At any rate, you can provide the missing guidance by saying

                    Path=[(sys:Int32)0]

    assuming you’ve previously declared

                    xmlns:sys=”clr-namespace:System;assembly=mscorlib”

    This says what you think it does:  “use the indexer that takes an int argument”.


    Subject: SketchFlow transitions between screens?
    Is it possible to create transitions between screens in SketchFlow?

    Answer:
    It should be doing this by default. The default transition is a fade, if you right-click a navigation connection in the map, there are a few more to choose from “Transition Styles”.


    Subject: RE: How to improve the text rendering of your .NET 4.0 WPF Applications

    Answer:
    Important caveat: Do not use TextFormattingMode=”Display” on text that is going to be scaled by a RenderTransform (or scaled in any way other than by changing the font size). It will end up blurry.

    Some more recommendations: http://blogs.msdn.com/text/archive/2009/08/24/wpf-4-0-text-stack-improvements.aspx


    Subject: RE: Partner's question about WPF-Image convert & Flash support

    Answer:

    There are external EMF->XAML converters:
    http://www.wpf-graphics.com/Paste2Xaml.aspx
    http://www.verydoc.com/emf2vector/emf-to-xps.html

    Indeed, WPF does not provide any native flash rendering.  I doubt we ever will.  Some options:
    1) Host a web browser.  Yes this is HWND interop code, so there are some compromises: the infamous airspace issues being the most prominent.

    2) For display only, you might look at a DirectShow filter, like: http://www.medialooks.com/products/directshow_filters/flash_source.html


    Subject: Property increment value i nBlend
    If you expose a numeric property on a type and it is available in the  property window you can change the value by dragging the cursor up, down, left and right.  Is there a way to tell Blend what the incremental value should be?

    Answer:

    Yes, you need to supply a design-time assembly that uses the NumberIncrementsAttribute.

    public sealed class NumberIncrementsAttribute : Attribute, IIndexableAttribute

    Name:

    Microsoft.Windows.Design.PropertyEditing.NumberIncrementsAttribute

    Assembly:

    Microsoft.Windows.Design.Interaction, Version=4.0.0.0

    http://blogs.msdn.com/unnir/archive/2009/03/22/writing-a-design-time-experience-for-a-silverlight-control.aspx


    Subject: pack: registration?

    I forget, how do you open a pack: URI?
    I tried using WebRequest.Create, but that gave me an error saying that pack: wasn’t registered… Then I tried using PackUriHelper to cause it’s static cctor to run, to try and get the prefix registered… PackWebRequest isn’t constructable (from what I can see)…

    Answer:

    [Multiple interesting data points]

    #1 System.Windows.Application has a static ctor where ResourceContainer package is added to PreloadedPackages so that downstream PackWebRequestFactory can find it. So you need to be running in the context of an Avalon application to get this.

    #2  If you use PackUriHelper class, the “pack:” prefix gets registered with the System.Uri class and this helps in performing the correct parsing and construction of System.Uri objects for pack Uris.

    The other registration is of the pack: scheme with WebRequest so that you can use WebRequest.Create method to return the PackWebRequest object. This can be done in your code. PackWebRequestFactory does not register it. You could use PackWebRequestFactory directly to get the PackWebRequest too –

    PackWebRequest request = (PackWebRequest)((IWebRequestCreate)new PackWebRequestFactory()).Create(packUri);


    Subject: RichTextBox viewable area

    Is there any way to get the viewable area in a RichTextBox?

    Answer:

    TextPointer upperLeftCorner = rtb.GetPositionFromPoint(new Point(0, 0), true /* snapToText */); TextPointer lowerRightCorner = rtb.GetPositionFromPoint(new Point(rtb.ActualWidth, rtb.ActualHeight), true /* snapToText */);

    You could refine this to get a tighter fit by looking at RichTextBox.ViewportWidth/ViewportHeight, to omit space for surrounding chrome like the possibly visible ScollViewer or Border. But for optimizing a property set on the viewable area first, including a small amount of extra content around the viewport is probably fine.


    Subject: ValidatesOnDataErrors not working on bindings inside an ItemsControl.

    I noticed that ValidatesOnDataErrors is not working on bindings inside an ItemsControl.ItemTemplate. I confirmed this problem has been fixed in Framework 4.0 but our target is 3.5.

    Answer:

    the workaround is to use the “long” form of ValidatesOnDataErrors:

    <Binding.ValidationRules>

                    <DataErrorValidationRule/>

    </Binding.ValidationRules>

     


    Happy coding!!

  • Jaime Rodriguez

    What is new in WPF and Cider on the .NET Framework 4 and VS2010 beta 2 release

    • 0 Comments

    This post is a quick recap of the most important changes for WPF and Silverlight developers in this Beta 2 release. I definitely will return to a few of these topics over the next few weeks, so stay tuned for updates and new posts. Please note that this post is NOT all-inclusive; there are lots of features and smaller bug fixes that I am leaving out. I will try to dig those up as we go along in the next few weeks!

    Also, I've listed links to the Beta 1 posts at the bottom of the post for those needing a refresh. I've also sprinkled links to the videos in our “WPF in VS2010 Beta 2 series” throughout the post, as well as listing them at the end.


    New in the Visual Studio 2010 Cider designer

    You can see a video with most of the Beta 2 updates in this 14 minute video with Mark Wilson Thomas.
    In the video, Mark shares a MUST USE registry key to improve the performance of Visual Studio 2010 Beta 2.

    For the record, this is in the readme, it is not a hack and Mark has documented it on his announcement:

    Registry Switch for improved performance
    Because of a late-breaking change, you will need to make a configuration change to see the best designer performance. This configuration change will not be necessary in the final released versions of the product.
    NOTE: Editing the registry can cause serious problems that may require you to reinstall Windows. Microsoft cannot guarantee that problems resulting from the incorrect use of Registry Editor can be solved. Use Registry Editor at your own risk. Refer to the article on registry editing for your OS (e.g http://support.microsoft.com/kb/136393) for advice. 
    1. Close any open VS instances
    2. Open RegEdit (as an administrator as needed)
    3. Select the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\10.0 key
    4. Right click and add key, type ClrHost
    5. In the newly created key, right click and add a DWORD32 with the name StartupFlags
    6. Set its value to 5
    7. Close RegEdit
    8. Start up Visual Studio and use as normal

    [10/28 update. Mark now has a disclaimer and it is in bold red on his page, so it must be important, go read it:

    1. The registry hack might create instability or increased Virtual Memory Usage in some VS scenarios.  If you see this, feel free to remove the config change and report it on Connect.
    2. Also, if you are not using Cider designer a lot (for WPF and Silverlight) the configuration change is not helping you. So don't enable it unless you are using the designer a lot. ]

    Here are my cliff-notes from the video:

    For WPF developers

    • The designer continues to stabilize.  All the features introduced in Beta1 – including improvements on the designer, brush editor, IntelliSense on binding markup extensions, data sources window- have been cleaned up and the performance has been boosted. 
    • The property browser has been updated with a new view that tells you what is the source for the value of a property (e.g. is the source set locally, from a style, binding, etc.).   This feature is proving incredibly handy based just on my one week of using it!
    • Support for StaticResources in app.xaml. Finally! No more long pack://application,,,/ syntax required.
    • Improved error handling, much like Blend, where the designer can isolate errors to a specific user control; the designer now ‘recovers’ and gives you meaningful information about the error.
    • Now there is design-time data support; compatible with Blend. 

    For Silverlight developers,

    • You finally get an interactive designer where you can drag & drop and get all the designer features available in WPF -  zero to 70 MPH in a single release- Cha-Ching!!

    New Graphics (minus text) features for the WPF run-time?  
           You can watch demos for most of these in this video with David  Teitlebaum.  You can get the demos for this video here.

    • Cached Composition. This feature allows you to “cache” any UI Element as a bitmap that can be persisted in video memory. The cache supports dirty regions, so it redraws when needed (with out you needing to detect it).  
      Cached elements can be live objects (e.g. a textblock) and can be transformed, rotated, etc.
      This feature is incredibly powerful for WPF scalability. If you watch David’s video you will see how he went from ~10fps on a live drawing, to 60fps when he cached it. I recently had a similar experience in a 3D viewer; my CPU decreased by 80% for all my drag & drops once I cached the 3D scene during the drags.
    • Layout Rounding allows WPF to avoid the blurriness that results in images and text when they are using layout with sub-pixel positioning.  This feature is in Silverlight 2; again, nice to have compatibility.
    • Pixel Shader 3 support expands the effects pipeline significantly since PS3 has a lot more instructions. A good reference on difference on # od instructions between PS2 and PS2 is at wikipedia.
      Note: The gotcha for this features is that Pixel Shader 3 does not default back to software rendering, so you will need to test to see if hardware supports the feature before you use it.
    • Animation easing functions allow designers to create more realistic, fluid animations. This feature matches the easing functions in Silverlight 3 and provides XAML compatibility.  Out of the box, you get  CircleEase, BackEase, ExponentialEase, Quadraticease, CubicEase, QuarticEase, Quinticease, PowerEase, Elasticease, BounceEase, and SineEase.  There is also an interface (IEasingFunction), so you can create your own easing functions and plug them into any of the existing animations via a new Dependency property on all stock animations. 
    • RenderOptions.ClearTypeHint allows you to turn ClearType on in scenarios where the system previously turned it off.

    New Text Features
    You can watch most of these improvements with insightful explanations in this Channel9 video with Chipalo Street.

    • A new text rendering stack improves the clarity and puts  the application developer in control of the rendering and formating options. With this new stack you choose between the old world WPF text (which worked well for some scenarios), and new text with comparable sharpness to Win32/GDI. 
      Configuring the text enhancements is handled mostly via two new attached properties:
      • TextOptions.TextFormatingMode allows you to control the metrics for formatting text. You get two options:
        • Ideal – is the old WPF, the glyphs maintain high fidelity with their outlines, and placement of the final glyph is not taken into account
        • Display – uses GDI compatible metrics and ensures glyph widths are in whole pixels (clarity of the text is much higher when text aligns to whole pixels)
      • TextOptions.TextRenderingMode allows you to control how the text is rendered.
        • Auto – respects the system setting; this is usually ClearType for most systems
        • ClearType – forces the rendering to Cleartype -this is what we were doing in earlier versions of WPF
        • GrayScale – renders grayscale, antialiased text
        • Aliased –  no antialiasing is used.
          Note: Per Chipalo, aliased vs. antialiased does not lead to perf differences; this surprised me.
    • Embedded bitmaps adds support for (mostly) East Asian fonts that contain bitmaps for some characters at small sizes.
    • Bindable Run is simply the old Run, fixed so that Run.Text is a dependency property and can be data bound.
    • Customization support for Caret Brush allows you to replace the Caret in TextBox, PasswordBox and RichTextBox. You can replace the CaretBrush with any brush. Go crazy!  You can also customize SelectionBrush and SelectionOpacity on all controls that support selection –including TextBox, RichTextBox, PasswordBox, FlowDocumentPageViewer, FlowDocumentScrollViewer and FlowDocumentReader.
    • Custom Dictionaries allows you to customize the dictionary used for spell checking in WPF applications. In previous releases, WPF used the OS dictionary, but did not allow you to extend it. Now with Custom dictionaries you can extend the dictionary to include your specialized industry lingo. 

    New Control & Data binding features

    • VisualStateManager support. VSM actually ships in the platform and all the controls have been tweaked to support Visual States. This means you can now customize Control templates using VSM and get higher compatibility with Silverlight.
      Note: Despite the VSM support in all the controls, the actual control templates were not changed, you will need to replace the template to use VSM.
    • Inheritance Context for Input Binding enables the MVVM scenario of  binding InputBinding.Command to a command in a ViewModel.  The Key and Modifiers property in KeyBinding are now Dependency Properties; same for MouseAction and MouseBinding.
    • DependencyObject.SetCurrentValue  is a new method introduced mostly for Custom Control authors.  SetCurrentValue method changes the effective value of the property, but existing triggers, data bindings, and styles will continue to work because the ValueSource for the property is not changed.  A lot of the controls in WPF were tweaked to use this, so their old SetValue calls were replaced with SetCurrentValue. I hear the recommendation is for custom control authors to use this method instead of SetValue; reccomendation makes sense, I am not sure if it applies 100% of the time, or just 99%; so use with 1% caution.
    • Databinding support for DynamicObjects.  With .NET 4’s support for dynamic keyword, a lot of people will be using DynamicObject (and I DynamicMetaObjectProvider).  You will be able to bind to these dynamic objects using the same syntax than a property of any other object. You will even be able to use typed DataTemplates (as long as you are using concrete typesthat derive from DynamicObject.

    New Windows 7 features

    • MultiTouch is fully functional in Beta2. WPF now has full support for multitouch including  manipulation, inertia, and raw-touch events.   The support is at UIElement, UIElement3D and ContentElement –which means every thing with LIFE in WPF supports Multitouch. 
      This topic is going to get its own blog post (and hopefully a video) soon, so stay tuned.
    • Taskbar support for Windows 7, including jumplists, progress bar, overlay icon, and thumbnail buttons (with WPF commanding support).  This topic will also get its own blog post soon.

    Deployment update
    You can watch a demo and get the whole picture from this Channel 9 video interview with Jossef Goldberg.

    • Client profile is critical to the deployment of the framework outside of managed enterprises. By subsetting the full framework to a client SKU, we will decrease download size, and improve the framework install times. 
      In Beta 2, client profile is near feature complete:
      • You can see it as its own separate, serviceable SKU
      • The tools have support for it, including the References dialog in VS2010 filtering for assemblies only in client profile SKU if that is what you are targeting. 
      • A few assemblies that were not in client profile SKU are now included, this increased the size to 30 MB, which is still a great improvement compared to full framework. 

    Hopefully this gets you caught up on beta2.  Time to play! Download visual Studio 2008 beta2.  Stay tuned for a few more posts on the topics above.

    LINK ROLL!!

    Beta 2 links:

    Beta 1 (but still relevant links)

  • Jaime Rodriguez

    Learn, network with MVPs, and have fun at the PDC Windows 7 Developer Boot Camp

    • 0 Comments

    Before and After

    We recently announced a free, all-day Windows 7 developer training the day before PDC. 

    Our goal for the day is to dive deep into the new most important kernel features, and also give you insightful advise into the new user mode developer features – including multitouch, taskbar, sensors & location, and graphics.  The day will be packed with insightful advise guaranteed to save you hours of reading articles, documentation, and blog posts. We are going to be punchy and direct!

    I am also pleased to announced that the MVPs attending PDC are joining us for the day, and are going to be hosting all the attendees for lunch; the lunch tables will have signs announcing the MVP technology to be discussed at that table;  you can drill down on that specialty and connect with our community champions and most valuable professionals.

    We are also adding to the boot camp the judging competition for the Code 7 contest; this will be a fun 30 minutes near the end of the day, you will see some very cool, inspiring Windows 7 projects developed by the community, and we will also have a few prizes to raffle for the boot camp attendees. 

    If you are still not ready to go home after all that,  you can hit the recently announced screening of the Visual Studio Documentary. 

    As you can see, the day is packed with great content, experts, and fun activities.  All of this for the low price of FREE!!
    You do still have to register.  All the details for the free registration are here. You do not have to be attending PDC, you can register for just the boot camp.  Of course, if you are coming to LA, might as well stay for the full PDC.
    Registration to the boot camp is on first-come-first-served basis, so don’t wait too long.

    About the agenda for the day, it is the same schedule than the workshops: 10 AM to 5:45 PM with lunch at noon and two breaks during the day.

    Our current outline divides the day into three two-hour sessions:

    • 10 AM – noon.  -- Getting the most out of Windows
      Mark Russinovich, Arun Kishan and Landy Wang are going to dive deep into the kernel improvements. Arun is going to demystify the scheduler, and Landy is going to spill all the details on the memory manager improvements in Windows 7
      Yes, I know, these are not the technical terms they would use, but their outline is the kind of deep stuff that makes my (as they call it, user mode) head hurt, so I had to simplify it.  The good news is that Arun, Mark and Landy will also be available after their two hour session for those of you who want to side line with them and keep going deep into their kernel bliss.
    • Noon to 1:15 – Lunch and network with the MVPs
    • 1:15 to 3:15 – Making the most out of your software
      Yochay Kiriaty and I will get deep into the shell improvements – taskbar, libraries and search-; we will also cover,  the new ribbon control, and the sensors & location platform (technically this belonged in the hardware session, but we had to fit it here to optimize the time).
    • 3:45 to 5:30ish – Getting the most out of today’s PC hardware.
      We will cover multitouch and Michael Oneppo will join and dive into the graphics improvements in Windows 7- including Direct2D, DirectWrite,  and DirectX11.
    • 5:30 to 6ish…  Code 7 Contest prizes
    • 6:30 the Visual Studio documentary.

    Again, must register to attend..  Don’t wait too long or you might be left out.

  • Jaime Rodriguez

    More on AERO Shake and WPF

    • 0 Comments

    A few follow-up questions (and answers) from this post on Aero shake in WPF Windowless apps .


    The code I posted does not work if your WPF WindowStyle=None window is maximized. Why is that?

    The shell detects the shake based on Windows movement, and when a window is maximized, it can not be dragged. This is a behavior defined by the shell :(

    Can’t you just ‘detect’ mouse move events and identify the shake gesture and then call the Shell’s API to do the shake?

    Unfortunately not.  The shell does not publicly expose APIs to implement the shake behavior – which is minimizing all windows except for the one that is being shaken-.

    Are we out of luck then to get Aero Shake on a ‘full screen’ app?

    I think that simulating shake (several posts on the web that do that) is not ideal.  Those posts do it to bring Shake to earlier versions of Windows that do not have it.   What I advised the person that did it was to not maximize their Window.  You can detect the available screen real-estate and size to that.

    this.Width = SystemParameters.FullPrimaryScreenWidth;
    this.Height = SystemParameters.FullPrimaryScreenHeight
              + SystemParameters.CaptionHeight;
    this.ResizeMode = ResizeMode.NoResize; 

    To most users (who are not looking to shake),  the window will still look like it is maximized. No difference.
    To a user that is looking to shake, the window can be moved (and shaked).  The mere idea of ‘shaking’ a full screen window is not very common, but in this case the app was partially transparent so it did need it.  All I did was allow the shake again using DragMove, and then resetting the position of the window back to 0,0 after the shake. 

     

    private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                this.DragMove();
                this.Left = 0;
                this.Top = 0; 
    
            }

    I am not claiming this is a best practice, but it worked good enough for my expectations.  If you want to see the code and decide if it works for your scenario, you can download a sample app from here.

    Why the emphasis on WindowStyle=None, does Aero Shake work on WPF apps with standard windows?  

    Aero Shake works fine with standard WPF windows;  no changes are needed to your WPF apps.  It is the windowless apps that needed the few lines I have shared in these posts. 

    At last, if you do not know what Aero Shake is, you can watch shake in action in this 15 seconds video.

  • Jaime Rodriguez

    Implementing Aero Shake in a WindoStyle None WPF Window

    • 0 Comments

    I just tried to implement Aero Shake in a WindowStyle=None WPF window.

    I had no clue what I would need to do; I figured I had to start by dragging the Window..   tried that, ran it just to see what would happen and voila! Windows 7 did the rest… 

    I am going to the movies (since I had budgeted 3 hours for this)..   Thanks Windows 7 Shell team!

    <Window x:Class="WpfApplication40.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300" MouseLeftButtonDown="Window_MouseLeftButtonDown"
    Opacity="0.5" WindowStyle="None" AllowsTransparency="True" >

    <
    Grid>
    <
    TextBlock Text="Shake me.. please" VerticalAlignment="Center"
    HorizontalAlignment="Center" FontSize="60"/>
    </
    Grid>
    </
    Window>

     

    private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
    this.DragMove();
    }
  • Jaime Rodriguez

    Platform Update For Windows Vista

    • 0 Comments

    Windows 7 is packed with lots of new “developer” or “platform” features

    We are confident most customers would benefit (better per, better UX) from running on Windows 7;  but we also acknowledge that adopting a new OS is not always immediate (specially for any large enterprise that recently rolled out Windows Vista). 

    For developers whose customers can’t move to Windows 7 immediately, Microsoft recently announced the “Platform update for Windows Vista” beta.

    The Platform Update for Windows Vista, brings a lot of the  Windows 7 goodness into previous OSes (Windows Vista and Windows Server 2008); the update includes Direct2D, Direct3D, DirectCompute, Windows Imaging Component (WIC)DirectWrite, XPS , and the Windows Ribbon) . 

    You can learn a lot more about the Platform Update here.  

    Enjoy!

  • Jaime Rodriguez

    WPF Discussion 090922

    • 0 Comments

    Raw, unedited, insightful and deep content from our internal WPF discussion…


    Subject: Any chance of INotifyCollectionChanged moving to the core .NET libraries?

    The  System.Collections.Specialized.INotifyCollectionChanged interface is defined in WindowsBase.dll (primarily a WPF assembly) but my customer believes it should be pushed down into the core BCL so that other project types can benefit from it without requiring a reference to WPF/WindowsBase.

    Is this planned for 4.0 or later?

    Answer:
    INotifyCollectionChanged, ObservableCollection<T>, and ReadOnlyObservableCollection<T> have been type forwarded into System.dll for .NET 4.


    Subject: Why TextRange.Load(MemoryStream, DataFormats.Xaml) can not work?

    I am trying to load a flowdocument from a Xaml file using TextRange.Load(MemoryStream, DataFormats.Xaml) method, but the following code does not work:

                FlowDocument f = new FlowDocument();

                TextRange range = new TextRange(f.ContentStart, f.ContentEnd);

                StreamReader sr = new StreamReader(@"TextFile1.xaml");

                string aa = sr.ReadToEnd();

                MemoryStream ms = new MemoryStream(System.Text.Encoding.Default.GetBytes(aa));

                range.Load(ms, System.Windows.DataFormats.Xaml);

    I know if I use XamlReader.Load method will do the trick, but I don’t understand why the above code can’t work. Is this a bug or I am missing something?

    Answer:

    DataFormats.Xaml (and XamlPackage) are misleading – when consumed by TextRange.Load they only work on a subset of xaml generated by TextRange.Save.  The TextRange.Save/Load api is intended for editing scenarios where you need to persist arbitrary selections that may cross element boundaries (e.g., you need to save half of a Paragraph).

    For your scenario, where you’re loading loose xaml from a file, XamlReader is the way to go.


    Subject: What is "Unlabeled time" in Visual Proiler that is part of Performance Profiling Tools for WPF?

    Answer:

    Any CPU time that we aren’t able to attribute to a specific WPF operation goes in the unlabeled bucket.  This includes time spent in CLR operations such as garbage collection and time spent in the application’s own code.


    Subject: Accessibility issue with WPF DataGrid and NewItemPlaceholder

    We’ve run into an accessibility issue with the WPF DataGrid concerning the NewItemPlaceholder.  Specifically, we’re re-templating the placeholder control in order to add a “real” click-here-to-add-a-new-item button.  However, none of the UI elements in the new template are available to accessibility-based automation (i.e. the button does not show up in UISpy or AccExplorer).  The template is set during the DataGrid LoadingRow event and looks like this:

    <ControlTemplate x:Key="SafeControlNewRowControlTemplate" TargetType="{x:Type DataGridRow}">

    <SelectiveScrollingGrid>

    <Button Content="Click here to add a new item." Margin="5,5,0,0" x:Uid="AssemblyDialogWindow_SafeControlAddNewItem" Click="OnSafeControlNewRowButtonClicked"/>

    </SelectiveScrollingGrid>

    </ControlTemplate>

    Answer:

    Yeah the AutomationPeers for all of the DataGrid components are structured around rows and cells. In your scenario you are retemplating a row (NewItemPlaceHolder row) so it does not have cells. Unfortunately the AutomationPeers do not recognize this. So you will in fact need to jump through some hoops to enable this scenario.

    • Subclass DataGridRowAutomationPeer and override GetChildrenCore to special case NewItemPlaceHolder row and return the visual children instead of the cells.
    • Subclass DataGridRow and override OnCreateAutomationPeer to return the subclassed DataGridRowAutomationPeer.
    • Subclass DataGrid and override GetContainerForItemOverride to return the subclassed DataGridRow.

    Subject: Adding ContextMenu to DataGrid header

    I am using WPF 4.0 DataGrid and want to add context menu only to the header. The way that I found to do is to add a ContextMenu setter property to a style and assign the style to the DataGrid.ColumnHeaderStyle.

    Answer: This is the right way of setting the context menu on DataGridColumnHeader (either using an implicit style for DataGridColumnHeader or setting it explicitly using ColumnHeaderStyle property).

    But this puts restriction that a style needs to be added to the ColumnHeader. Performing SetValue on “DataGridColumnHeader.ContextMenuProperty” somehow sets it for the entire grid. The context menu should only be for the header.

    Answer:  This won’t work. When one uses ‘DataGridColumnHeader.ContextMenu’ property, note that one is using the property which internally happens to be the same for DataGrid too (because ContextMenu is defined on FrameworkElement and all controls share the same property definition). Hence that would end up setting the value of DataGrid itself.

    Is there any way to add context menu only to the header w/o having to set ColumnHeaderStyle?

    Answer:  Use implicit style for DataGridColumnHeader. But honestly I don’t see any difference from using ColumnHeaderStyle.


    Subject: Adding HierarchicalDataTemplate via UI?

    How can I add a HierarchicalDataTemplate for Silverlight 3 via the Blend 3 UI (without typing in the class in XAML)?

    Answer:

    Steps:
    1. Create a new sample data
    2. Click on the triangle of  “add simple property”, select “convert to Hierarchical Collection”
    3. Drag the converted Hierarchical Collection to artboard
    View the xaml, notice the Blend generated HierarchicalDataTemplate is bound to the generated tree view.

    Here is a more complete TreeView editing experience write-up:
    http://shawnoster.com/Blog/Silverlight-TreeView-Connecting-Lines-And-Blend-3-Support-for-HierarchicalDataTemplates


    Subject: debugging an unmanaged exception in WPF app.

    tried to debug my application I saw the following message “The debugger does not support debugging managed and native code at the same time on this platform.”

    How could I enable only native code debugger without managed one?

    Answer:
    There may be other ways, but this should work.
    Right-Click on the solution, select  “Add Existing Project” and select the compiled exe.
    Set the exe project as the startup project.
    Right-Click, go to Properties and set “Debugger Type” to “Native Only”


    Subject: API that can determine whether a keystroke yields printable characters or not
    I have a KeyDown event and System.Windows.Input.KeyEventArgs event arg e.
    Is there any API that I can use to determine whether this e.Key is printable or not? Or is there any API I can get the character of this keystroke?

    Answer:
    Generally, no. KeyDown to text conversion is pretty stateful, and you don’t have access to this state. Most of it is maintained by the OS.


    Subject: XBAP and multi touch in Windows7

    Will all multi touch features in WPF 4 be available when running on Windows 7 as XBAPs as well?

    Answer:
    Yes, manipulation and touch events are available in PT. However you cannot implement your own touch device.


    Subject: X:Name and Name property

    I have a quick question on why do we have Name for some of the Classes and have to use x:Name for the classes related to Animation/Timelines. Why is this difference in the framework and no uniformity?

    Answer:

    XAML uses [RuntimeNameProperty(“somePropName”)] on classes to signify when a property is the “Name” property (and thus aliased with x:Name).
    XAML treats the two interchangeably when a type does have a RutimeName declared.
    If a tag has both, that is an error.

    Reasons for where we ended up:
    · We wanted WPF to not have to require 2 namespaces to have a Named object.
    · We didn’t want to hard code all “Name” properties as the Name.


    Subject: WPF colour depth rendering support

    Hi all,

    I'm working on an application that displays DICOM images, the spec allows for images to have greater than 8 bits per channel which most if not all of my test data does have and is very common in medical images. I read on http://blogs.msdn.com/dwayneneed/archive/2008/06/20/implementing-a-custom-bitmapsource.aspx that "The WPF rasterizer only natively renders bitmaps in Bgr32 and PBgra32 formats" (In the 'WIC in WPF' section, 5th paragraph), is there any way to have a WPF application render an image in PixelFormats.Prgba64 or PixelFormats.Gray16 (or an equivalent)?

    Thanks,

    Answer:

    No. As Dwayne’s blog notes, the WPF rendering pipeline operates in 32-bit only, so all images are format converted to that before being processed.


    Subject: Workaround for IsDeferredScrollingEnabled bug

    When using a ComboBox inside of a ScrollViewer with IsDeferredScrollingEnabled=true scrolling in the ComboBox does not work correctly.

    Answer:

    You’ve certainly hit a bug and we are recording one for this scenario. As for a workaround, you can set IsDeferredScrollingEnabled to true for the ComboBox as well to get all the scrollviewers to work correctly. Like this.

    <StackPanel.Resources>

    <Style TargetType="ComboBox">

      <Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="true" />

    </Style>

    </StackPanel.Resources>


    Subject: WindowStyle.None + ResizeMode.CanResize vs. NoResize

    clip_image002I’m trying to recreate a window like the volume window, where there’s minimal chrome and cannot be resized.

    WindowStyle.None renders a window without a title bar. ResizeMode.NoResize will make a window not resize (surprise, surprise). Unfortunately, when you use them both together, there is no window chrome at all. I’ve tried setting the min/max height/width, which works, but I still get the resize mouse icon when I hover over the window border. Is it possible to render a minimal chrome without the resize icon?

    Answer:

    I think you should be able to use what you have and p/invoke to set the Window's native style to include WS_BORDER.
    There isn't a combination in WPF's Window that supports what you're trying to express.


    Subject: Window chrome size

    Is there a way to get the height of the title bar and width of little border on the left in a window. I’m trying to create an overlay window via databinding (would use popup, but it doesn’t seem to respect bindings like Window does) so I need to add in the chrome size to find the global position of the window’s client area. Or maybe there is an easier way?

    Answer:

    You might try Visual.PointToScreen to see if it does what you want.  I think it gives coordinates in actual device pixels, so if you need to position your overlay using WPF's 1/96" units, you'll have to multiply by 96/systemDPI.  With some effort, you can get this scale factor from HwndTarget.TransformFromDevice.


    Subject: RE: Viewing WPF applications over Citrix

    What would be the implications of running WPF over Citrix.

    Answer:

    All versions of WPF since WPF 3.5 SP1 have remoted (both with Remote Desktop and Terminal Server) using Bitmap Remoting.

    Bitmap remoting works as follows:

    • The application is rendered on the server using WPF’s software rasterizer
    • As the application runs, the server keeps track of which regions of the application’s window are newly dirty and need to be updated
    • When a region needs to be updated, the server creates a compressed bitmap of just the dirty region and sends that to the client
    • Once the client has drawn that bitmap to the appropriate place on its own window, the client window is up-to-date

    Given how this remoting mechanism works, performance can be maximized in several ways:

    • Dirty regions should be kept as small as possible so the least amount of data is sent over the wire
    • Ambient animations should be turned off.
      • For instance, setting a window background to an animating gradient would cause the entire window to be invalidated / redrawn every frame
    • The system does not optimize away occluded parts of the application
      • For instance, an animation that is completely hidden behind some other opaque element will still cause dirty region invalidation / bitmap generation to occur.  Remove these from your application.
    • Dirty regions should be created as infrequently as possible
    • Turn off as many animations as possible
    • For those animations that can’t be eliminated completely, lower the animation framerate using the DesiredFramerate property
    • Dirty Region Bitmaps should be as simple as possible to maximize their compression
    • Application running over TS should favor solid colors over gradients or other exotic fills (unnecessary images, etc), especially for application pieces that will be redrawn frequently
    • Avoid operations that are especially slow when rendered in software
      • BitmapEffects / Effects / ShaderEffects, especially blurs and drop shadows with large radii, are quite slow in software
      • 3D – the 3D software rasterizer is substantially slower than rendering in hardware

    Subject: Spell checker does not pick up the current input language if it changes

    If I create an empty application, with:
    <TextBox SpellCheck.IsEnabled="True" />
    And I enter text in English, all is good. If I delete all my text in that textbox, change my input language to German (for example), and input German words, it will still be spell checking in English. If I restart the app with my input language set to German, it will spell check correctly.

    Answer:

    It’s by design.  TextBox doesn’t track input language (unlike RichTextBox, which will tag every character entered with the current input language).  TextBox can’t track the input language of individual characters because it contains nothing but Unicode.  So,

    1. If TextBox.Language is set, the speller will respect it.

    2. If TextBox.Language is unset/default (en-us), the speller uses a heuristic, reading the input language set when spelling is enabled.

    Language is an inheritable property, so setting it on any parent element will affect a TextBox.  The speller will honor any Language value that is not default -- local, inherited, or styled.


    Subject: turn off bitmap effects?
    Is there a registry setting to turn off bitmap effects?

    Answer:

    No there isn’t. But in 4.0 all the *BitmapEffect classes are either no-opd or redirected to their *Effect equivalents (for the case of DropShadow and Blur).


    Subject: RadioButton/ToggleButtons with DataBinding

    Does anyone have an example of a group of RadioButtons or ToggleButtons working with DataBinding?
    We've found it quite difficult to get this working in a straightforward way. 

    Answer:
    Ralph, yes there are known issues about RadioButtons and other Controls setting local values upon user interaction and hence clobbering app set Bindings in .Net 3.5

    I've worked around this issue in .NET 3.5 SP1.  Here's how I data bind a group of radio buttons to an enum-valued property:

    <StackPanel>

    <RadioButton Content="New folder"

                   IsChecked="{Binding Path=PublishTarget,

                               Converter={StaticResource equalityConverter},

                               ConverterParameter={x:Static local:PublishTarget.NewServerFolder},

    Mode=TwoWay}"

    GroupName="1"/>

      <RadioButton Content="Existing folder"

                   IsChecked="{Binding Path=PublishTarget,

    Converter={StaticResource equalityConverter},

    ConverterParameter={x:Static local:PublishTarget.ExistingServerFolder},

    Mode=TwoWay}"

                   GroupName="2"/>

      <RadioButton Content="Local folder"

    IsChecked="{Binding Path=PublishTarget,

    Converter={StaticResource equalityConverter},

                               ConverterParameter={x:Static local:PublishTarget.LocalFolder},

                               Mode=TwoWay}"

                   GroupName="3"/>

    </StackPanel>

    Setting each radio button's GroupName to a unique value prevents the bindings from getting clobbered when the user clicks on a radio button.  Here I'm relying on the data source to implement INotifyPropertyChanged, which will tell the other radio buttons to update.  A similar approach should work for radio buttons in an ItemsControl.

  • Jaime Rodriguez

    Expression Studio TuTorialS Starter Kit

    • 5 Comments

    Via Arturo Toledo (internal email).  The Expression team released four great Expression starter kits today..

    Introduction to Prototyping with Sketchflow in Expression Blend 3
    Discover Sketchflow, a new feature set in Expression Blend 3 that helps you define the concept for user experiences in early stages of the design process. From sketches to wireframes to protoypes of simple or high definition, Sketchflow provides you the right tools to communicate your ideas and gather feedback from others.

    Venture into Gaming with Behaviors in Expression Blend 3 
    Learn more about how to build a traditional "bricks" game using Expression Blend 3 Behaviors. Simply drag and drop Behaviors over objects in your artboard to easily add powerful and sophisticated functions like animation, physics, interactivity, data connection, effects and more. All without coding. The ever growing Behaviors Gallery at expression.microsoft.com is always available for you to download new behaviors.

    Discovering SuperPreview in Expression Web 3
    Learn more about SuperPreview, a new visual diagnostics tool in Expression Web 3. In this Starter Kit you will be provided with detailed guidance on how to leverage SuperPreview to diagnose issues across multiple browser, all with full rendering fidelity and detailed control.

    Support for Silverlight in Expression Web 3
    Learn how to leverage the new and easy to use Silverlight support features in Expression Web 3. Then take your websites and publish them to an FTP location without having to leave Expression Web.

     

    -------

    I just got done watching the Sketchflow tutorial videos; they were excellent!!  Moving to behaviors next :)

    Enjoy!!

  • Jaime Rodriguez

    WPF discussions 08082009

    • 0 Comments

    Raw/unedited useful WPF advise..


    Subject: Control Verifier
    From: Samantha Durante, our controls PM

    Answer:
    I just wanted to let you know that we’ve just released Version 0.1 of the WPF Control Verifier tool. 
    WPF Control Verifier is a tool that verifies the correctness of WPF Controls. This tool is geared towards WPF Control developers with the goal of providing a set of verifications that all controls can run and consume. Version 0.1 includes one category for verification – default style verification. These tests verify that your control can be styled such that its dependency properties are inheriting or template binding correctly. Future versions will include additional categories of verification.

    You can download this tool in the new WPF Test Tools release at the WPF Codeplex site.  


    Subject: Application checking .NET 3.0 is installed
    What's the best way to determine if the user's computer has .NET 3.0 installed?

    Answer:
    Check the Registry.
    The official guide:
    http://msdn.microsoft.com/en-us/library/aa480198.aspx#netfx30_topic14


    Subject: RE: Binding doesn't seem to work: System.Windows.Data Error: 4
    Long discussion on how RelativeSource (binding to Ancestor) is indeterminate with regards to when parent is added to the tree;

    Answer:
    In general, RelativeSource looking for an Ancestor type isn't robust against delayed addition to the tree, and not at all against reparenting.  I only learned this earlier this week, debugging a similar issue.  Consider instead making "MyProperty" an inheritable property, and just binding to Self, MyProperty.

    (Jaime’s personal take added now).  I do use RelativeSource within generated items in ItemsControls. Seems usable there and seems like a good place to apply it; if the scenario was different (less items in particular and shallow trees) then inherited property sounds good too.


    Subject: Knowing if a control is partly occluded

    I’m working on adding tooltips to controls that are partly occluded on mouse hover (like the Outlook folders pane does). What’s the right way to know whether something has been partly occluded?

    Answer:

    ///<summary>
    /// This eliminates the part of bounding rectangle if it is at all being overlapped/clipped by any of the visual ancestor up in the parent chain
    ///</summary>
    internal Rect CalculateVisibleBoundingRect()
    {

        Rect boundingRect = Rect.Empty;

        boundingRect = new Rect(_owner.RenderSize);
        // Compute visible portion of the rectangle.

        Visual visual = VisualTreeHelper.GetParent(_owner) as Visual;
        while (visual != null && boundingRect != Rect.Empty && boundingRect.Height != 0 && boundingRect.Width != 0)
        {
            Geometry clipGeometry = VisualTreeHelper.GetClip(visual);
            if (clipGeometry != null)
            {
                GeneralTransform transform = _owner.TransformToAncestor(visual).Inverse;
                // Safer version of transform to descendent (doing the inverse ourself and saves us changing the co-ordinate space of the owner's bounding rectangle),
                // we want the rect inside of our space. (Which is always rectangular and much nicer to work with)
                if (transform != null)
                {
                    Rect clipBounds = clipGeometry.Bounds;
                    clipBounds = transform.TransformBounds(clipBounds);
                    boundingRect.Intersect(clipBounds);
                }
                else
                {
                    // No visibility if non-invertable transform exists.
                    boundingRect = Rect.Empty;
                }
            }
            visual = VisualTreeHelper.GetParent(visual) as Visual;
        }

        return boundingRect;
    }

     


    Subject: RE: BitmapImage.StreamSource - best practice for closing the stream?
    If I use BitmapImage, then set in the StreamSource, no one seems to ever close the stream.  The net effect is this locks the file in memory – preventing file renames, etc.

    Answer:
    By default images are delay decoded. Set the CacheOption to BitmapCacheOption.OnLoad to force eager decode of the stream. 


    Subject: CollectionView, Sort Descriptions, Turkish I, and Custom Sorts

    Given a CollectionView, and some SortDescriptions, how does one ensure that the sorting is correct for the current culture? Should I use Custom sort?

    Answer:
    ListCollectionView’s sorting uses the Culture property.   If you don’t set this, it’s set to agree with the Language of the client element.  For example,

                    <ListBox  ItemsSource=”…” Language=”tr-TR”/>

    will sort in Turkish.

    The CustomSort lets you define your own comparison logic.  You can pay attention to whichever columns you like, and choose case-sensitive or insensitive.


    Subject: DecodePixelWidth
    I’d like to investigate DecodePixelWidth to reduce memory consumption when viewing large images on the design surface. 
    Is there a way without loading the image itself to grab the metadata that would tell me what the size of the image is?


    Answer:
    Unfortunately no.


    Subject: Getting HyperLink content
    I'm trying to get the text of a hyperlink via code, and I can't find it.

    Answer:
    TextRange range = new TextRange(link.ContentStart, link.ContentEnd);
    string text = range.Text;


    Subject: Implement Attribute x:Uid
    Is it possible to implement the localization attribute x:Uid? We would like to implement this attribute without inheriting from UIElement and make it possible to use XAMLReader/XAMLWriter API.

    Answer:
    If you’re working with 4.0, you can set the UidPropertyAttribute on your type and it’ll set whatever property you need it on.
    There is no way in 3.X.  Uid was hard coded in the system to only work with UIElements. Uid is ignored on all other types at runtime.


    Subject: Invisible Hyperlink can still receive focus

    For following xaml, the hyperlink hyper1 is invisible, but can still receive keyboard focus, I need to set it’s Focusable to false to stop it receiving focus, is this the expected behavior?
    <TextBlock Visibility="Collapsed"><Hyperlink x:Name="hyper1"/></TextBlock>

    Answer:
    This appears to be a bug in TextBlock and is not specific to Hyperlink.  If you replace the Hyperlink with a Button, it loses Tab navigation completely while other panels work as expected.
     


    Subject: Mouse wheel in winform interop scenario

    Hi,

    Our project embed a Dunas chart control inside a WindowsFormHost. We want to support mouse wheel on it for zooming. The dunas document specifically call out that mouse wheel does not work unless the control is focused (indeed, when there is no focus, the chart does not receive mouse wheel message, and I guess this is not specific to dunas control but to general winform control too). The  initial thought is to programmatically set focus on the dunas control. However, this is apparently bad that if other elements get focus this stops working.

    Now my goal is to enable mouse wheel without messing with focus. If I am able to intercept mouse wheel message (no matter focused or not) I can work with the control to simulate zooming. The first attempt was to derive from WindowsFormHost and override WndProc to see if I can receive mouse wheel message there without being focused. It did not working (not surprising).

    After looking into MSDN I found ComponentDispatcher class. So I tried the following code:

    ComponentDispatcher.ThreadFilterMessage += delegate(ref MSG msg, ref bool handled)

                {

    if (msg.message == 0x20A) /*MouseWheel*/

                    {

                        System.Diagnostics.Trace.WriteLine("Receiving mouse wheel message");

                        System.Diagnostics.Trace.WriteLine("msg window " + msg.hwnd);

                        System.Diagnostics.Trace.WriteLine("WindowsFormsHost handle : " + this.wfhost.Handle);

                    }

                };

    Well now I do get mouse wheel message. But I get ALL of them even if the mouse is not on the control. The windows handle in the message is not the same as reported by WindowsFormHost, it is actually the main window (which is logical since this essentially comes from main message pump).

    Answer:
    Windows will deliver the WM_MOUSEWHEEL to the HWND with focus.  So you will have to start from there.  You can either subclass that window proc, or you can use the ComponentDispatcher to watch the messages come through the message pump.  The HWND in the message will be whatever HWND has focus – such as the main App window.

    You can then look at chart.IsMouseOver to decide whether or not to respond to the message.


    Subject: Override tab ordering of panel

    We implemented our custom Panel class and want to change the tab navigation behavior.
    Does anyone know where to override the default behavior?

    Answer:
    You can set KeyboardNavigation.TabNavigation property on the custom Panel to the mode you like.
    Then TabIndex property on subelements if you want to change the Tab traverse order.


    Subject: Question with ReadOnly RichTextBox

    I have a window that contains a RichTextBox control used to display read-only text. As such, I have set the IsReadOnly property to ‘True’ so that the text inside the RichTextBox is not editable. However, setting this property also disables many keyboard navigation commands, such as arrow up/down, page up/down. Some commands, such as text selection (Ctrl+A, Shift+Up/Down/Left/Right) still work. Does the RichTextBox require any additional configuration for the keyboard navigation commands to work when IsReadOnly is set to True?

    Answer:

    In <=3.5sp1, keyboard navigation is not fully supported when IsReadOnly is set to true. In 4.0, we’ve added a new property to TextBoxBase (IsReadOnlyCaretVisible) which enables both the caret rendering and keyboard navigation in read only mode.


    Subject: Is it possible to utilize the functionality of DocumentViewer's FindToolBar programatically?
    Answer:

    Unfortunately the search API used by the document viewers is not publicly exposed and as far as I know there are no plans to expose it in the near future.

    -----------------

    Subject: SplashScreen Bug

    Hello Folks,

    Our client has a bug with the use of the SplashScreen class present in the Framework 3.5 Sp1. The bug are the same that the one describe in these differents threads:

    · http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=378575

    · http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=362735

    It seems that this bug is corrected en the next release of WPF (4.0) But our client needs to release our application

    Answer:

    You can work around both of those issues using the existing SplashScreen by not using the fade out.To do that you’ll need to write a main method that looks something like this:

    [STAThread]

    public static void Main(string[] args)

    {

    SplashScreen sp = new SplashScreen("splash.png");

        sp.Show(false);

    Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => sp.Close(TimeSpan.Zero)), DispatcherPriority.Loaded);

        WpfApplication1.App app = new WpfApplication1.App();

        app.InitializeComponent();

        app.Run();

    }

     


    Subject: Question about ListView sorting feature

    When I am developing sorting feature for the ListView, I observed a interesting behavior. Could someone help to identify whether it is by design? I also attached the project.

    Say I have a listview, and the values in column “Test Enabled” are all the same. When I click the column header, the column will be sorted.

    Step 1, see picture 1, no column is sorted.
    Step 2, click column header of column “Test Enabled”, column “Machine” is sorted. (Could anyone tell me why?).
    Step 3, click column header of column “Test Enabled”, no changes.
    Step 4, click column header of column “Test Enabled”, no changes.

    The way I implement the sorting is very simple:

    //sort the machines.

    ICollectionView view = CollectionViewSource.GetDefaultView(this.Machines);

    view.SortDescriptions.Clear();

    view.SortDescriptions.Add(new SortDescription(sortColumn.Tag as string, direction));

    view.Refresh();

    Questions:

    1. In step 1, why column “Machine” is sorted when I try to sort column “Test Enabled”?

    2. In step 3, 4, why wouldn’t the list view change anymore?

    Picture 1:

    clip_image001

    Picture 2:

    clip_image002

    Picture 3:

    clip_image003

    Picture 4:

    clip_image004

    Answer:

    LCV.CustomSort only specifies the comparer, the actual algorithm is implemented by Array.Sort (it’s a Quicksort).

    When you click the ‘Test Enabled’ column, we sort by that column only.  Since all the values in that column are equal, any permutation of the rows is sorted.  The actual result depends on the implementation of the sort algorithm, not on the data at all.  (In other words, it’s not really true that it sorts by ‘Machine’;  all you can say is that the algorithm permutes the rows in some arbitrary way.)  When you click the column again and nothing changes, that only means that Array.Sort produces the same result given the same input – not terribly surprising.

    It’s pretty difficult to implement a sorting algorithm that is both stable (records with equal keys end up in the same relative order as they began) and efficient (O(n log n) with small coefficient).    I think you’ll find that the algorithm Marco pointed to (http://thomas.baudel.name/Visualisation/VisuTri/inplacestablesort.html) is quite a bit slower than Quicksort in practice.

    There’s no way to replace the sorting algorithm used by the collection view.  If you want a more intuitively deterministic result, you can add a second SortDescription that says how to compare records that are equal w.r.t. the first SortDescription.

    BTW, your code actually sorts the array twice.  The collection view automatically refreshes whenever you change the sort descriptions, so you sort once for view.SD.Add() and a second time for view.Refresh().   If you added a second SortDescription, you’d sort three times.  The right way to do it is:

                    using (view.DeferRefresh())

                    {

                                    view.SortDescriptions.Clear();

                                    view.SortDescriptions.Add(….);

                                    view.SortDescriptions.Add(…);

                    }

    This turns off the automatic refresh until you’re done changing things.

  • Jaime Rodriguez

    RenderTargetBitmap tips

    • 2 Comments

    Quite often,  I run into the “RenderTargeBitmap gave me an empty image” or “RenderTargetBitmap did not render my visual”..  
    Hint: this happens a lot to people putting stuff into StackPanels.

    The problem is that renderTargetBitmap is working at the Visual layer to render the visual and to do the rendering, it looks at the local properties of the visual (as expected).
    Layout happens at a different (higher) layer in the platform but often ‘parents’ to your visual will apply offsets or transforms to your visual to position it, since the parent is setting these properties on your actual visual, these properties will be picked up by RenderTargetBitmap logic.

    The best (and simplest) workaround I have seen came from Adam Smith ( WPF team lead and reliable WPF know it all). It simply wraps the Visual into a VisualBrush that it then draws into a DrawingContext.

    private static BitmapSource CaptureScreen(Visual target, double dpiX, double dpiY)
    {
        if (target == null)
        {
            return null;
        }
        Rect bounds = VisualTreeHelper.GetDescendantBounds(target);
        RenderTargetBitmap rtb = new RenderTargetBitmap((int)(bounds.Width * dpiX / 96.0),
                                                        (int)(bounds.Height * dpiY / 96.0),
                                                        dpiX,
                                                        dpiY,
                                                        PixelFormats.Pbgra32);
        DrawingVisual dv = new DrawingVisual();
        using (DrawingContext ctx = dv.RenderOpen())
        {
            VisualBrush vb = new VisualBrush(target);
            ctx.DrawRectangle(vb, null, new Rect(new Point(), bounds.Size));
        }
        rtb.Render(dv);
        return rtb;
    }

    I like that workaround the best, and that is the one I use most of the time. 
    I know other people who workaround this same issue by wrapping the visual they are going to RTB in a Border. This abstracts any transforms that were being applied by the original parent, and now RTB works well.  I obviously don’t like this one as much since it ‘imposes’ on my Visual Trees.  Still, it works, so it is a choice.
     

    Here is a screenshot of a sample demonstrating the issue and the solutions:

    image
     

    The first column is the original images and buttons. They are all in a StackPanel.  The top 3 items in this panels are not wrapped inside a border, the latter 3 are wrapped in a border.

     

    The second column, shows what you would get if you just use RenderTargetBitmap.  Notice that the button and second image are missing; the reason is cause the StackPanel is offsetting them and RTB is picking that up.   
    Do notice that even with no special workaround, the ones wrapped in the border worked OK.

     

    The third column shows all the items rendered with the workaround above. Note that it works for all items, including the ones that had border.

     

    The source code for this small sample (including the workaround) is here.

    While I am into RenderTargetBitmap, a reminder to look at this KB article (and or QFE).
    In 3.5 SP1, we fixed a few leaks for RenderTargetBitmap, but there is still one open; it has to do with doing RenderTargetBitmap of a 3D scene that has VisualBrushes inside the scene.

  • Jaime Rodriguez

    WPF discussions 090626

    • 1 Comments

    Emails from our MS internal discussions. Lots a great tips.


    Subject: Advise for running WPF apps over Citrix

    Answer:
    All versions of WPF since WPF 3.5 SP1 have remoted (both with Remote Desktop and Terminal Server) using Bitmap Remoting.

    Bitmap remoting works as follows:

    • The application is rendered on the server using WPF’s software rasterizer
    • As the application runs, the server keeps track of which regions of the application’s window are newly dirty and need to be updated
    • When a region needs to be updated, the server creates a compressed bitmap of just the dirty region and sends that to the client
    • Once the client has drawn that bitmap to the appropriate place on its own window, the client window is up-to-date

    Given how this remoting mechanism works, performance can be maximized in several ways:

    • Dirty regions should be kept as small as possible so the least amount of data is sent over the wire
    • Ambient animations should be turned off
      • For instance, setting a window background to an animating gradient would cause the entire window to be invalidated / redrawn every frame
    • The system does not optimize away occluded parts of the application
      • For instance, an animation that is completely hidden behind some other opaque element will still cause dirty region invalidation / bitmap generation to occur.  Remove these from your application.
    • Dirty regions should be created as infrequently as possible
      • Turn off as many animations as possible
      • For those animations that can’t be eliminated completely, lower the animation framerate using the DesiredFramerate property
    • Dirty Region Bitmaps should be as simple as possible to maximize their compression
      • Application running over TS should favor solid colors over gradients or other exotic fills (unnecessary images, etc), especially for application pieces that will be redrawn frequently
    • Avoid operations that are especially slow when rendered in software
      • BitmapEffects / Effects / ShaderEffects, especially blurs and drop shadows with large radii, are quite slow in software
      • 3D – the 3D software rasterizer is substantially slower than rendering in hardware

    Subject: Is there any support in WPF for “bottom-up” bitmaps?
    I’m using BitmapSource.Create with an unmanaged memory buffer. The buffer comes from a Win32 DIBSection with a +ve height, which indicates a bottom-up DIB.

    Answer:
    Wrap it in a TransformedBitmap. 
    return new TransformedBitmap(bmp, new ScaleTransform(1,-1));

    [extra tip]
    Note that I think each call to CopyPixels() on the TransformedBitmap will run the scale transformation again. You can avoid this by caching the result in a CachedBitmap and using the CB instead


    Subject: Getting DependencyProperty value from WinDBG
    I have a dump of a WPF process and am trying to get the value of a DependencyProperty of UIElement.  Does anybody know how this can be done?

    Answer:
    1. Pull out the value of _packedData.
    2. _packedData & 0x0000FFFF will give you the GlobalIndex.
    3. Go to the DependencyObject on which you want to query the property and get access to the _effectiveValues array.
    4. Go through the EffectiveValueEntry objects, looking at the _propertyIndex field until it matches the index you calculated in step 2 (the array should be sorted by property index).
    5. _value is the value of the property on that DependencyObject.


    Subject:  Difference between nulll and x:Null for brushes

    I know there is a difference but I can’t remember. I think it had something to do with hit testing (but I can’t remember for sure).

    Answer:
    No difference.  You're probably thinking of null (No hit test) versus Transparent (Can be hit).


    Subject: Disable auto-word selection in FlowDocumentViewer
    How can I make FlowDocumentViewer select character by character when I use the mouse?

    Answer:
    For FlowDocumentPageViewer, you can use flowDocumentPageViewer.SetValue(TextBoxBase.AutoWordSelectionProperty, false). FlowDocumentScrollViewer doesn’t auto-select words by default.

    Internally, the selection code shared by text boxes and FlowDocument viewers relies on TextBoxBase.AutoWordSelectionProperty. We don’t currently expose the property on anything other than TextBoxBase.


    Subject: Blend units.
    Any reason why Blend3 outputs font size in WPF “units” and not the actual pt value. If I change the FontSize on a TextBlock to “11pt”, 14.667 is written out.

    Answer:
    Blend 2 always displayed text units in pixels. This was confusing to most designers who are used to thinking of fonts in terms of points. In Blend 3 we added an option where you can choose whether you want points or pixels as your display in the Property panel. This is under the Units tab in the Options dialog.

    In terms of the XAML output, we had wanted to output the same units as shown in the UI but Silverlight does not support the pt syntax in XAML so we decided (for cost and consistency reasons) to just leave it as pixels in the XAML for V3.  It is something for us to consider improving in the future though.


    Subject: Disable IME on TextBox
    Is there a setting to disable using IME on a textbox, or some other means of not allowing a user to use it?

    Answer:
    <TextBox InputMethod.IsInputMethodEnabled=”false” />


    Subject: DateTime property in the Properties editor of Blend
    I have a question regarding how Blend handles a control property which is of type System.DateTime.  I am trying to understand how the property editor would interpret a string such as 20/05/2001. Would it take into account the regional settings of the computer or is it tied up with the implementation of the control itself?

    Answer:
    Blend will use a text editor to read and display DateTimes, and will parse input based on the locale settings of your machine.  In xaml, it is always stored in an invariant format(year-month-day).


    Subject:  (summarized) issue w/ WPF not matching GDI on how a custom font is rendered

    Answer:
    There is no expectation that WPF font rasterization will match GDI\GDI+ rasterization. For example if the font does not have italic or bold variants GDI will emulate bold and italic WPF will not.


    Subject: DPI interop issues...

    I have a drag/drop gesture that draws a drag/drop feedback in a transparent WPF window. The problem is in tracking the mouse position I had to use interop to Win32.GetCursorPos and that works, when the operating system is in 96 DPI mode.  But when you change the OS DPI to something else, like 120 or 150 DPI then this doesn’t work because positioning the transparent WPF drag/drop feedback window requires WPF device independent coordinates (essentially 96 DPI) so I need to do a conversion


    Answer:
    Have you looked at Visual.PointFromScreen?  It can be used to convert screen coordinates from APIs such as GetCursorPos into Device Independent Units


    Subject: Game loops in WPF?
    wondering how easy it would be to write a custom "game loop" within the WPF framework. By game loop, I mean pumping my own events on a custom Dispatcher so I can control the framerate of my app.

    Answer:
    You can write your own message pump. Just don't call Dispatcher.Run. You need to pump messages, and you need to call ComponentDispatcher.RaiseThreadMessage as appropriate. Use reflector to see what Dispatcher.PushFrame does.

    Of course, this still may not give you what you want for a "game loop"...


    Subject: Is there a way to prevent exception if DataContext is null?

    This is just an example.

    I have a Image which is Databind to some dynamic source (image source) and it works fine and it is all done in xaml. Can we provide some defaule image source incase DataContext becomes null?

    Answer:

    FallbackValue is your friend: http://msdn.microsoft.com/en-us/library/system.windows.data.bindingbase.fallbackvalue.aspx


    Subject: Listening to selective ETW Events

    I’m writing performance tests where we want to listen to the WClientUceNotifyPresent ETW event to calculate frame rates.  However, I haven’t found provider flags to listen to it, along with a limited set of other events.

    Answer:

    With WPF 3.0-3.5 you unfortunately don’t have a lot of options.  You should make sure that you’re using verbosity level 4 (as opposed to 5).

    If you’re on CLR 4.0 we have much more granular flags so you’ll be able to turn on a flag specifically for Graphics related events which should help .  If you have a recent drop (post Beta1) you should find our event manifest installed in \windows\microsoft.net\framework\v4.0\wpf\wpf-etw.man which lists the available flags.  You will need either flag 1 `General` or flag 0x1000 `Graphics` depending on what drop you have.


    Subject: Way to check if an UIElement is visible in ScrollViewer

    Is there any way to check if an UI element is already showing in a scroll viewer?

    Answer:
    [Not right one, but works]
    Use reflection to invoke ScrollViewer.IsInViewport method?

    [Final]
    I wouldn’t recommend this for production code.
    Is there a reason you don’t want to call BringIntoView on elements that are already visible? All handlers of RequestBringIntoView I know of no-op on visible elements.

     

  • Jaime Rodriguez

    New release of WPF Toolkit, now with charts!

    • 1 Comments

    The June release of the WPF toolkit went live today, it now includes the charts imagethat come with the Silverlight toolkit.

    David Anson has the scoop and a great sample on the charts

    The other controls (Datagrid, VSM, and DatePicker) also include a few minor fixes (check the release notes).
     
    There is not an update for the WPF ribbon; we are still hopingthe update to ribbon comes after (or around same time) as .NET4 beta2. 

    Enjoy the charts and the new toolkit, please don’t forget to send feedback.

     

    PS. – Congrats to David Anson for the release; he has been the biggest advocate for the charts making it into WPF. I am sure he put some ‘over-time’ given how much they are doing with the Silverlight control toolkit too.  Thanks David!

  • Jaime Rodriguez

    THANKS CHICAGO. Here is the content.

    • 3 Comments

    Last friday, we had the pleasure of delivering the last stop in the WPF for LOB tour: Chicago. ChicagoXamlized

     

    The training was very lively, with lots of people from all over the mid-west, and a few people from other further places…  It was a lot of fun at a good location (despite a shaky start with a microphone, that only lasted 45 mins ).  Definitely a good way to finish the tour..

    The content for Chicago is now posted:  Decks  and demos 

     

    Thanks to all the Chicago attendees!!

     

    And thanks to every one else who helped us with the tour.  This has been a lot of fun and very enlightening and inspiring to us.

     

     

    .

  • Jaime Rodriguez

    WPF in LOB TOUR, PHOENIX CONTENT

    • 0 Comments

    Last week’s stop in the WPF for LOB tour was Phoenix.   PHXXAMLIXED

    Great weather, a great audience, and good times.
    Having been twice in Phoenix this month I have to say they have a really great .NET community. Congratulations and thanks for joining us for the training!!

    Here are the decks and the demos.

    Thanks again Phoenix!!   Next stop: Chicago; c u there on friday.

     

    My guess is that most Americans know this, but I did not.  The picture is from a well known place in Phoenix, called Camelback mountain. 
    Courtesy of Terry Stanley, a training attendee (and now a XAML expert).

  • Jaime Rodriguez

    Programming differences between WPF and SIlverlight, a WHitePaper

    • 3 Comments

    Wintellect just posted a great 70 page white paper on codeplex about the “programming differences between WPF and Silverlight”.  

    I have not dissected it yet, but from a quick scan it looks very useful.
    I will be printing it and dissecting it on my flight to the next (and last) WPF for LOB Tour stop: Chicago.

    Please share feedback on the paper.   Is it useful?? What is it missing?? Is it a fair assessment of the status on our continuum.

  • Jaime Rodriguez

    WPF discussion 090605

    • 2 Comments

    You know the drill: Raw/unedited WPF discussions from inside the mothership.


    Subject: Accessibility tree, and collapsed elements

    We have some UI that we’re collapsing (Visibility=Collapsed). However, even after it’s collapsed, it *seems* to be participating in the accessibility tree (shows up in UIspy). Is this the correct behaviour?

    Answer:
    It seems that this behavior is expected. However UI Elements that are collapsed should have the IsOffScreen property set to true. You could probably filter on that flag.


    Subject: Blur the focus of a window

    With WPF, how can you blur (lose focus) a window?

    Answer1:
    There are essentially 3 types of focus, which type do you want to blur?  There are:

    · Logical focus.  This is essentially a way of marking which IInputElement in a given scope should receive keyboard focus if that scope gains keyboard focus.  Within elements that are marked as a focus scope, there will be 0 or 1 logically-focused child elements.  A focus scope is determined by FocusManager.SetIsFocusScope/FocusManager.GetIsFocusScope, and logical focus can be cleared by using FocusManager.SetFocusedElement on the focus scope to null.

    · Keyboard focus.  This is similar to Win32 focus; only one IInputElement on the thread with Win32 focus can be the Keyboard.FocusedElement.  In 3.0/3.5/3.5 SP1, the only way I know of to clear WPF keyboard focus also involves clearing Win32 focus, by calling ::SetFocus(NULL) from user32.  In WPF 4.0 there is a new method coming along, Keyboard.ClearFocus(), which will clear only the WPF keyboard focus.

    · Standard Win32 focus.  WPF keyboard focus is typically kept in-sync with Win32 focus (in that the focused HWND typically contains the Keyboard.FocusedElement), so doing operations which affect HWND focus will generally affect the Keyboard.FocusedElement.

    Answer2:

    Of course, you can always make an element lose focus by focusing another element, too.  Calling Keyboard.Focus on some other element should result in PreviewLostKeyboardFocus/LostKeyboardFocus being raised on the element losing keyboard focus.  Similarly, calling FocusManager.SetFocusedElement to some other element in the focus scope should result in PreviewLostFocus/LostFocus being raised on the element losing logical focus.

    Confusingly, perhaps, calling Keyboard.Focus(null) will not clear keyboard focus, but will instead focus the active PresentationSource's root visual.  This can result in Keyboard.Focus(null) actually focusing another element, and not clearing focus.


    Subject: How do I change properties on the Navigation Bar in a WPF Frame?

    I'm working on a page based WPF application, and I want to change the size of the navigation bar in the Frame hosting my pages. I set NavigationUIVisibility="Visible" in order to see the navigation bar, now how do I change properties on the navigation bar like it's size?

    Answer:
    The built-in navigation UI is not directly customizable. You’ll have to replace the entire ControlTemplate of Frame, possibly using the built-in one as a base. This is easy with Blend. Some resources:
    http://windowsclient.net/downloads/folders/wpfsamples/entry5121.aspx
    http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c98f9b2a-a910-45cd-acdc-fa5b222b7460/


    Subject: Scroll issue with hosting a winform within WPF

    I am having an issue trying to scroll a winform control hosted within WPF. I have a view (WPF UserControl) that has 3 elements. A checkbox, a hosted winform control (gray window below) and a combobox.

    Answer:
    Here’s an illustration of this technique for another source: http://blogs.msdn.com/ryanvog/archive/2009/01/20/clipping-legacy-content-hosted-inside-a-wpf-scrolling-region.aspx.


    Subject: RE: Themes\Generic.xaml

    Answer:
    Only resources that are referenced with StaticResource from within the same resource dictionary (i.e. within Generic.xaml) can be strings. For everything else, you must use either a type key ({x:Type Foo}) or a ComponentResourceKey. Styles with no key specified default the key value to the TargetType of the Style.


    Subject: Asynchronous Commands and Dispatcher

    I have a command which executes a long-running operation using BackgroundWorker.  The command exposes a State property to which the UI can be bound to indicate that the operation is in progress or has finished.  The results of the command are bound to a TreeView.  Whenever an element is added to the results, the command does so by calling Dispatcher.BeginInvoke so that the element will be added to the results collection on the UI which causes the TreeView to be updated.  I call the BeginInvoke method with a priority of Background.  Once the command is finished executing, it updates its state to say it’s finished. 

    The problem is that when there are hundreds of elements that have been added to the collection, the UI thread hasn’t finished processing all of those operations that have been queued on the Dispatcher by the time the command says it’s finished.  So the command says it is finished even though the UI thread is still busy processing all the queued operations. 

    One solution is to have the Command update its State property by having the Dispatcher do it via the BeginInvoke call with the same priority.  That would cause the Dispatcher to update the Command’s state once all the other previously added operations have been processed.  But I’m not sure that’s the right approach; it feels very hacky.

    Is there a better way to do this?

    Answer:
    Keep track of the last operation you BeginInvoke over to the UI thread from the worker thread.  When the worker thread is done, before it updates the state property, have it call DispatcherOperation.Wait() to wait for the UI thread to finish.


    Subject: RE: Blocking till message loop empty?

    Answer:
    Nope.  Dispatcher.Invoke, when called on its own thread, will implicitly use Dispatcher.PushFrame.


    Subject: RE: Bounding rectangle for objects on canvas

    Answer:
    GetDescendantBounds returns the bounds without applying any Visual properties like Clip, Transform, Offset, Effect…
    Canvas.Left/Canvas.Top are mapped to Visual.VisualOffset and Visual.VisualTransform. To take the bounding box from what we call “inner coordinate space” (closest to children) to “outer coordinate space” (closest to parent) you have to apply all the transforms, clips, etc. Note that an effect might change your transformation too…

    The easiest way to get the outer bounds is to call on the parent GetDescendantBounds as long as the parent does not have any “vector content” (think ink).  For UIElements you provide “vector content” via OnRender, for DrawingVisual you call RenderOpen, etc. If the parent had any content, it would be included in the descendant bounds. The naming is a little unfortunate since it is not purely “descendant”. We originally had the functionality only consider descendants, but lots of people thought it was what it does now…


    Subject: Disable script debugging for WebBrowser?

    This option exists in the WinForms web browser, is there a way we can access this option in the WPF web browser also? We are having catastrophic issues with modal script debugger popups that make the browser too annoying to be useful.

    Answer:

    Get the native IWebBrowser2 and set the Silent property. See the Community section of the WebBrowser class reference (http://msdn.microsoft.com/en-us/library/system.windows.controls.webbrowser.aspx) for how to get IWebBrowser2.

  • Jaime Rodriguez

    Silverlight3 PlaneProjection Primer

    • 2 Comments

    A while ago, I cracked open Silverlight3’s PlaneProjection (aka 3D perspective transform ) feature. Below you should find the basic intro plus all the advanced stuff that had not been documented when I tried to learn it. It is a long read, if you are already an expert, skip to the “3D scene” section to read the interesting details.

    The post comes with this application that I used to learn and illustrate the points.  Source for the app is here.
    Click on the Figures below to go to the respective page on the demo app. SL3 is required!  You might need to maximize your screen to see the demos. 

    Introducing PlaneProjection
    Silverlight3 introduces a new Projection property on UIElement.   The property is of type Projection (an abstract class).
    In SL3, the only implementation of Projection class is PlaneProjection, which is an implementation of a 3D PerspectiveTransform. As of SL3 beta1, the implementation is software-based (so not hardware accelerated today).
    The UIElement that is projected into this 3D scene is interactive even if projected. Both front and back are interactive.


    PlaneProjection = Transforms + 3D scene

    For me, it is easiest to think of PlaneProjection as a wrapper for a 3D scene and series of 3D Transforms that you can apply to a UIElement to get it to ‘project’ in 3D space.

    The transforms that PlaneProjection applies to its UIElement are: 

    1. A TranslateTransform exposed via LocalOffsetX, LocalOffsetY, LocalOffsetZ in PlaneProjection.
    2. A set of RotateTransform   represented by the CenterOfRotationX, CenterOfRotationY and CenterOfRotationZ  and the RotationX, RotationY an RotationZ properties.
    3. A TranslateTransform(3D), exposed via GlobalOffsetX, GlobalOffsetY, GlobalOffsetZ

    Before I get into these transforms, let’s cover the coordinate system.

    Silverlight 3D coordinate system

      Print

    This system is similar to what Silverlight uses in 2D:
    +Y increases as you go down the vertical axis, 
    +X increases as you go to the right.
    +Z increases towards the viewer.

    Note: WPF uses a different system, called Right hand system,  in WPF, the Y increases as you towards the top on the vertical axis. 

     

     

     

     


                   Figure1. Coordinate System

     

    RotateTransform
    A RotateTransform rotates the object around an axis (X,Y,or Z). 
    You specify the CenterOfRotation (which is normalized, 0 to 1, as a percentage of the actual object size) for the axis, and then you specify the angle in degrees for the Rotation.

     

    imageOn Figure 2, you can see an Image of a duck rotated around the X Axis.  You first see the original, and then four rotations at 40, 80, 120, and 160 degrees. All of the rotations are the same for each row, but the second and third row have a different CenterOfRotationY property.

    The second row has CenterOfRotationY = 0.1; it rotates near the top of the UIElement (10% from the top).  

    The third row has CenterOfRotationY = 0.9;  so it rotates near the bottom of our UIElement.

    While looking at Rotations of 120 and 160 degrees, notice that there is no back material to our object. Silverlight acts as if back was transparent, letting you see the front material but rotated since you are watching from the back.

                                                                                                                              

                                                                                                                                 Figure 2. Rotate Transforms

    You may wonder what happens if I stack two objects in say a Canvas, one on front of the other, like this:                                                                                                                                             
                                                                                                                                                          
    <CanvasWidth="300"Height="300">
      <Canvas.Projection>
        <PlaneProjection
    RotationX="120"/>
      </Canvas.Projection> 
      <Rectangle
    Fill="Red"Width="100"Height="100"/>
      <Rectangle
    Fill="Black"Width="100"Height="100"/>
    </Canvas>

    We have a Red rectangle, right behind a Black one?  What is the back material now if we rotate the Canvas to see the back?
    The back material is still  the Black rectangle; it looks like Silverlight projects what is visible on the screen, so you get the back of the Black rectangle. 

    Rotations can be negative numbers; a rotation of –50 degrees looks like a rotation of 310 degrees; however, if you are animating you will see these animate in opposite directions (and 310 flips a lot more )yet they end up at same spot. 

    For the most part, that takes care of rotate transforms.  The only other thing to notice is that since we are transforming a 2D object on an Axis, the CenterOfRotationY affects RotationX,  and the CenterOfRotationX affects the RotationY.


    Translate Transforms.
    A TranslateTransform simply moves the object by an Offset vector. For example: an object at 1,1,1 with an offset of 50,74,-1 will end up at  51, 75, 0).   The units are Silverlight units relative to the screen; more on this below when we cover the 3D scene.

    PlaneProjection exposes two translate transforms:  A GlobalOffset and a LocalOffset transform:

    GlobalOffset transform
    The GlobalOffset Transform moves the object relative to the screen’s axis. This means the X,Y,and Z offset are in  the coordinate system I showed above in Figure1. Think about it as a translation after the rotation has happened.  The object is rotated first, and then after that, the resulting, rotated object is simply moved or translated.  This model is similar to what we see in 2D space.


    LocalOffset transform
    The LocalOffset as a translate transform applied prior to the rotation.  We already established that the CenterOfRotation affects the rotation.  Consider what happens if we first translate the object and then rotate it around a specific CenterOfRotation,  since the translate transform does *not* change the CenterOfRotation, you end up rotating around the axis with the translation applied.   That is what a LocalOffset transform does.

    Figure 4 on the right shows you what happens with a LocalOffset + Rotation combination applied. 

    imageRow1 shows three images in a spot (marked by red border).  Each image has a different frame (or border) and a different rotation. Green has RotationY=50;  Yellow RotationY=130 (so 180-50).  The third image (black border) has no rotation at all.

    Notice that since first row has not translate transforms, therefore the rotations are in-place (within the red border).

    Row2 shows same images +rotations), but LocalOffsetX=250.   The image in the black frame shows where the image is located after the translation; it is 250 units to the right of the red border (on X axis). Notice that the rotation is not in place any more (not within the red borders). In this row, the center of Origin is 0.5, so the images at 50 and 130 rotations are at symmetrical distance from the center of the red border (which is our center of origin, at 0.5).  

    Row3 has LocalOffsetX=250 and CenterOfOriginX=0.1.
    Since 0.1 is < 0.5, our CenterOfRotation is to the left from the one on previous row; since the center of rotation is farther away from the actual image, our rotation is the widest here.  The yellow frame is furthest from the red border.  
                                                                                                                              Figure 4. LocalOffset Transforms

    The fourth rotation has CenterOfOrigin=0.9, so this time we are moving our CenterOfOrigin closer to where the image was translated to, so our rotation is less wide than it was at both 0.5 and 0.1 . 

     

    That should cover the transforms!   If you need to play more with this, try the sandbox from the demos page.

    Now we get to the other half of PlaneProjection: a 3D scene. 

    The 3D scene
    A 3D scene usually consists of a Camera,  Lights, a mesh (the shape of your object) and a material (used to “paint” or “cover” your object ).  You need to know the Position of the camera (relative to the objects in the scene) and the FieldOfview angle.

    Print 

    Figure 5 shows the basic elements of a 3D camera placement. 
    F == field of View (in degrees or radians)
    D == distance (on Z plane) from the camera to the XY plane
    H == ActualHeight of object in our XY plane

     

     

                                                                                                                             

                                                                                                                                              Figure 5.  Basic 3D scene

    Those are the basics of a 3D scene, let’s now cover the Silverlight 3 specifics: 

    FieldOfView == 57.0  degrees
    At first, I was slightly concerned that I could not change field of view, but then I noticed that Silverlight does  not clip the 3D scene.  PlaneProjection works similar to RenderTransform where as you scale your UIElement, you can go over the UIElement’s render bounds (ActualHeight/ActualWidth) and the transform does not affect layout.  This means if your container does not clip, then field of view is irrelevant as you are seeing everything regardless.    


    image
    Figure 6 shows Field Of view and clipping interaction 

    Row1: A Canvas with two rectangles inside it. The blue rectangles take half the canvas space and the red rectangle takes 1/3 of the Canvas space.

    Row2: With a PlaneProjection with GlobalOffsetZ= 500,  the Canvas is a twice its original size. Notice there is no clipping.  This is default SL3 behavior, so field of view is fairly irrelevant as you are seeing the whole scene most of the time.

    Row 3: Same PlaneProjection applied to original Canvas, but this time the border hosting the original Canvas is clipping at 300x120..  So you only see partial scene.   Again this is not default behavior but for those wanting to clip, you know it can be done. 

     

     

                                                                                                                                     Figure 6. GlobalOffsetZ = 500, 2x.

                                                                                                                                                                                                                                          

    D = 999

    The next thing on the scene is the distance from camera to xy plane.  The answer there is a weird 999. The number I am certain, the behavior I am still trying to grasp .  Let’s explain:

    image

    If D was distance to camera and it was 999, then  when you did a GlobalOffsetZ > 999, the object should  not be in the scene, but what SL 3D does is allow for Zindex to be > 999 and then it rotates (as if you were looking at the back I assume).

    Figure 7 shows:
    Row 1: Original object. Rectangle with a gradient. This is very small on purpose (since it is scaled a lot when we increase ZIndex).  

    Row 2: Same object, but GlobalZIndex = 900.  [so 99 away from 999].
    Still looking at the front of the rectangel.


    Row 3: Same object, GlobalZindex = 1098 [so 99 over 999]. Notice that the we are looking at the back of the object.  It is the same size than 900.

    Row 4:  Has two objects. 
    First object = original + GlobalZIndex = 1899 (900 over 999), notice we are looking at the back of object but it is not scaled much. Second object  is Original object + GlobalZIndex = 99. It is same size as GlobalZIndex = 1899 and we are looking at the front.    
                                                                                                                                  Figure 7. GlobalZIndex > 999 

    If you are wondering why when you look at the API for PlaneProjection the default value for GlobalOffsetZ and LocalOffsetZ is 0 and I am saying the camera is at 999,   PlaneProjection applies the D = 999 is by moving the object before you get the scene, so the distance to the camera is there, but you don’t see it (or can’t change it) from the API.

    What about H? why does it matter?
    H is relevant because it tells you where the camera is in relation to the XY plane.  Not the distance to it, but where within that plane the camera is located. The short answer is that the camera is at the center. The long answer is that there is some scaling going on to make that happen. 

    For sizing of our scene, the math would go along H = 2*D*tan (F/2); since both F(57) and D (999) are fixed, then H should also be fixed (1084), but of course our UIElement is not of that same size, so the object is  scaled and aspect ratio is maintained.

    For the most part, you do not notice this scaling (nor should you care), but if needed you can use this knowledge to accomplish two things:

    1. Position the camera
    2. Create a 3D scene where multiple objects of different sizes appear to be in the same scene, with a common camera angle.

    image

     

    Figure 8.
    Let’s go back to our earlier example where I showed you a clipped scene,  this time the canvas in the last row is 500x120 instead of 300x120. if you see it before changing GlobalOffSetZ, visually it all looks the same. 

    When you animate GlobalOffsetZ, you notice the center of origin of the Projection is farther to the right ( at 250, which is the first third in the rectangle, so our rectangle would no longer clip, part of it is visible. 

    [I removed the clip on the border so you could see the scene, but it is easy to see that some of the red rectangle is still fitting in the border that was clipping the whole rectangle earlier.

     

                                                                                                                                               Figure 8 – Canvas to position camera.

     

    The example above is not that exciting or enlightening; you can accomplish some thing similar with a few transforms, so I am not proposing that you change the size of your containers to manipulate the camera, however the trick does come in handy when you have UIElements that are of different sizes but need to “integrate” into a 3D scene; and the UIElements need to be rotated separately.  If you are familiar with WPF, this would be like having multiple GeometryModels within a scene; you rotate these independently, but relative to a single camera and lights scene.

    Since I explained earlier that camera is located relative to the “center” of each UIElement, there fore getting multiple objects of different sizes to have the camera in the exact same spot is not doable unless we workaround it, and the workaround is to apply a Canvas to wrap each of my UIElements, and size all wrapper canvases to the same size, this way as I rotate them and manipulate them, they all have same relative CenterOfOrigin.

    imageFigure 9 demonstrates this trick.    
    Row1 shows a canvas with rectangles in it. The rectangles have slightly different sizes.

    Row2 shows the rectangles translated to GlobalOffsetZ = 500 (twice original size).
    Notice that the “top” of the rectangles are not aligned (unless the height of the rectangle was the exact same prior to the transform). I used the redlines to demonstrate the differences after translation.

    Row 3 translated the canvas instead of the rectangles, notice the top of the rectangles are aligned.

                                                                                                  Figure 9. Using same size Canvas to align UIElements
                                                                                                                      
    to get same Center of Origin.

    OK that covers most of what I found out on Silverlight’s PlaneProjection. I do have a useful sandbox page for playing around with a lot of these concepts.

     

    On the overall 3D API, I think it is quite simple, yet it lets you do a lot.    

  • Jaime Rodriguez

    Thanks New York. Here is the content.

    • 2 Comments

    The third stop in the “Windows Presentation Foundation for Line Of Business Tour” NYXamlized was  New York City, last Friday and Sat.

    We had a great  crowd, mixed with WPF newbees and experts; this drove us to long training days with lots of questions on both sides of the spectrum. 


    Thanks to the attendees for sticking it out!

    The decks are here.  The demos are here.

    Our last two stops are coming up quickly:
    Phoenix (this weekend) and Chicago (next week).

    Thanks again, New York ( and Philadelphia, and Boston, and New Jersey and any one else who came from out of town).

  • Jaime Rodriguez

    high level deck on Sharing code between WPF and Silverlight

    • 2 Comments

    This week, I had the pleasure of presenting at the “Phoenix AZGroups Scott Guthrie event”  (with Scott and Glenn).

    The deck that I presented is here. It includes a small section on some of the most relevant differences between WPF and Silverlight (3); any one wanting to know the differences, should check it out.  If you have a difference you would like me to add, please email me or add a comment here.

    --
    I have to thank all the people that attended the event and our hosts Scott Cate and Joseph Guadagno. I flew down thinking it was a ‘smaller event’ (maybe 300 people) and was incredibly surprised with what they put together; it felt like a one-day conference, with ~800 people registered, great food and location, and huge give aways ( netbooks, Flip HD cams, books, etc.. ). Very, very impressed, congrats to the usergroup on such a great event.  

    PS --  I will come back to the sharing code between WPF and Silverlight topic; in preparation for the talk, I spoke to 8 companies (agencies, ISVs, enterprises, etc.) doing code sharing already; overall, they were positive.  it is not seamless, but it can definitely be done.  If you want to see the client continuum in action, check Telerik’s SalesDashboard; built with high % of shared code between WPF and Silverlight; it uses prism too].  they give out the source for it too. Nice!

Page 3 of 9 (222 items) 12345»