blog community

Welcome to blog community Sign in | Join | Help
in Search

Erno de Weerd

About software development and training

  • Silverlight and the Mouse(Wheel) part II

    I wrote about Silverlight and the mouse(wheel) before and the responses are pretty good. One question that stuck to my brain and has been asked in forums is how to actually have controls like the ListBox respond to the MouseWheel event.

    First some code

    After decorating a ComboBox like this:

       1: <m:MouseSupport MouseWheel="ComboBoxOnMouseWheel">
       2:     <ComboBox>
       3:         ...
       4:     </ComboBox>
       5: </m:MouseSupport>

    It is pretty easy to add this code:

       1: private void ComboBoxOnMouseWheel(object sender, SilverlightMouseSupport.MouseWheelEventArgs e)
       2: {
       3:     ComboBox comboBox = sender as ComboBox;
       4:     if (comboBox != null)
       5:     {
       6:         if (e.Delta > 0 && comboBox.SelectedIndex > 0)
       7:         {
       8:             comboBox.SelectedIndex--;
       9:         }
      10:         else if (e.Delta < 0 && comboBox.SelectedIndex < comboBox.Items.Count -1)
      11:         {
      12:             comboBox.SelectedIndex++;
      13:         }
      14:     }
      15: }

    But as you will notice when testing this code the ComboBox only responds to the wheel when it is collapsed. I tried adding the decorator to the ItemsPanel but that froze the entire Silverlight application. I see no solution for that.

    On to the ListBox

    To make a control that uses the ScrollViewer to scroll its content you need to access the ScrollViewer that is in the template of the control. For some reason the GetTemplateChild method was made protected so the only way to get it you need to sub class the control and add a little code:

       1: public class ListBox : System.Windows.Controls.ListBox
       2: {
       3:     public ScrollViewer ScrollViewer
       4:     {
       5:         get
       6:         {
       7:             return GetTemplateChild("ScrollViewer") as ScrollViewer;
       8:         }
       9:     }
      10: }

    This ListBox now has a ScrollViewer property that can be used in code like this:

       1: private void ListBoxOnMouseWheel(object sender, SilverlightMouseSupport.MouseWheelEventArgs e)
       2: {
       3:     //note: this is a special ListBox, not a standard Silverlight listbox.
       4:     ListBox listBox = sender as ListBox;
       5:     double scrollStep = 10;
       6:     if (listBox != null)
       7:     {
       8:         ScrollViewer scrollViewer = listBox.ScrollViewer;
       9:         if (scrollViewer != null)
      10:         {
      11:             if (e.Delta > 0 && scrollViewer.VerticalOffset > 0)
      12:             {
      13:                 scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset - e.Delta * scrollStep);
      14:             }
      15:             else if (e.Delta < 0 && scrollViewer.VerticalOffset < scrollViewer.ScrollableHeight)
      16:             {
      17:                 scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset - e.Delta * scrollStep);
      18:             }
      19:         }
      20:     }
      21: }

    I have tried to encapsulate this behavior into the ListBox class itself but the problem I ran into is that to make it easy to use I need a way of manipulating the template of the ListBox to add the decorator. It is easy to replace an entire template of a control but I wanted to add the decorator to the existing template in runtime. That is not possible as far as I can see.

    I updated the download with this code so you can test and try for yourself.

    Concluding

    It looks like a hack. And it is. To get this working we need the Silverlight Base Control developers to help us out on this.

    Download here.

  • Interfaces and compatibility

    Sticking to industry standard interfaces can safe your life... Last week I found out that an interface that I have been using for years and years might become more common than expected.

    For years manufactures created weak implementations that most of the time didn't stick to the original interface definition. That might have had something to do with patents and stuff.

    I can wait for good, solid, fitting and inspiring implementations.

    Read the announcement here.

  • Silverlight and the Mouse(Wheel)

    The requested feature is simple: I want full mouse support in Silverlight. I want to use the mouse wheel and the right mouse button.

    After reading numerous blog posts and coding several proofs of concept I found that it is no easy task to get there. (Yes, browsers should be named as part of the evil axis)

    First the good news:

    1. Mouse wheel support is possible.
    2. I created a very handsome (if I may say so) decorator-like control to add mouse wheel support to a Silverlight application.
    3. No javascript writing needed.
    4. You can download it here (look at the end of this post)

    The bad news:

    1. Right mouse button support is a disaster.
    2. I did not add this to the decorator because I can not get a cross-browser solution to work correctly.

    The details on the good news

    Browsers have different ways of getting the wheel event data. First of all: the browser events are different. Here is how I solved that:

       1: private void AttachBrowserMouseWheelEvent()
       2: {
       3:     if (HtmlPage.IsEnabled)
       4:     {
       5:         if (HtmlPage.BrowserInformation.UserAgent.Contains("Firefox"))
       6:         {
       7:             HtmlPage.Plugin.AttachEvent("DOMMouseScroll", this.ProcessOnMouseWheel);
       8:         }
       9:         if (HtmlPage.BrowserInformation.UserAgent.Contains("MSIE") ||
      10:             HtmlPage.BrowserInformation.UserAgent.Contains("Opera") ||
      11:             HtmlPage.BrowserInformation.UserAgent.Contains("Safari"))
      12:         {
      13:             HtmlPage.Plugin.AttachEvent("onmousewheel", this.ProcessOnMouseWheel);
      14:         }
      15:     }
      16: }

    Note that I only tested this code on IE7 and FF2 and FF3.

    A major difference between this code and several examples I found on the web is that I register for the Plugin events, NOT the document or page events. Another difference is that I try to register only one single event; most samples on the web register all and might end up getting the same event multiple times.

    Once you get the correct event you have to parse the event data and of course this is also different for different browsers.

       1: public void ProcessOnMouseWheel(object sender, HtmlEventArgs e)
       2: {
       3:     if (_isMouseOverChild)
       4:     {
       5:         double delta = 0;
       6:  
       7:         ScriptObject eventObj = e.EventObject;
       8:  
       9:         if (eventObj.GetProperty("wheelDelta") != null)
      10:         {
      11:             delta = ((double)eventObj.GetProperty("wheelDelta")) / 120;
      12:  
      13:  
      14:             if (HtmlPage.Window.GetProperty("opera") != null)
      15:                 delta = -delta;
      16:         }
      17:         else if (eventObj.GetProperty("detail") != null)
      18:         {
      19:             delta = -((double)eventObj.GetProperty("detail")) / 3;
      20:  
      21:             if (HtmlPage.BrowserInformation.UserAgent.Contains("Macintosh"))
      22:                 delta = delta * 3;
      23:         }
      24:  
      25:         if (delta != 0)
      26:         {
      27:             bool handled = OnMouseWheel(delta);
      28:             if (handled)
      29:             {
      30:                 e.PreventDefault();
      31:             }
      32:         }
      33:     }
      34: }

    Don't get me started on this it only shows how decent people like me end up solving problems that shouldn't be our's in the first place.

    So, how do we get this code in our precious little Silverlight applications? All examples that I found on the web require page-wide handling of the events or subclassing controls but I wanted a the event to be fired per Silverlight control and I wanted to be able to get rid of this helper code with the least amount of hassle as soon as Microsoft comes out with a real solution.

    I wanted a decorator. Silverlight has no decorator (WPF does...) So I browsed to Codeplex and looked up the code on the Silverlight Viewbox which should be a decorator to find out how they solved that. Whoohoo for open source: I was able to copy-paste most of the code (let me know if I violated any copyrights doing that). This caused the client code to be able to look like this:

       1: <UserControl x:Class="SilverlightApplication1.Page"
       2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       4:     xmlns:m="clr-namespace:SilverlightMouseSupport;assembly=SilverlightMouseSupport">
       5:     <Grid>
       6:         <m:MouseSupport MouseWheel="TextBoxOnMouseWheel">
       7:             <TextBox Text="Scroll the mouse wheel above this textbox."/>
       8:         </m:MouseSupport>
       9:     </Grid>
      10: </UserControl>

     

    As you can see: no special requirements, just a namespace and a wrapping control (decorator).

    BTW: wouldn't it be nice to have attached events (like attached properties) so you could write this:

       1: <m:MouseSupport>
       2:     <TextBox m:MouseSupport.MouseWheel="TextBoxOnMouseWheel" Text="Scroll the mouse wheel above this textbox."/>
       3: </m:MouseSupport>

    Although there is no need to edit the TestPages (Html or Aspx) that are generated by Visual Studio, I did edit the Html page because I wanted to be able to use multiple Silverlight controls and the generated javascript simply lacks support for that. So any differences in this page are entirely optional. No need for javascript coding to be able to use the MouseSupport decorator.

    Details on the bad news

    For some reason publishers of browser plug-ins think it is necessary to bother the users of our (Rich Internet) applications with the fact that that particular area of the browser is using Silverlight or Flash/Flex/JavaFX by having a hard-coded context menu (right mouse button menu) that allows the user to configure the plug-in. As nice as that may be for a developer, for a user it is totally inappropriate. What would you think when you right-click in Word and you get a menu that allows you to change the wallpaper of your desktop?

    So what to do? I tried to add oncontextmenu="return false;" to the Html body or the plug-in tag. This does work but not in Firefox and causes a non-XHTML 1.0 violation. In Firefox, the context menu is still appearing but by right-clicking a second time the event does trigger but that silly context menu is still there. So I resolved to kill this feature from the decorator. If you know how to fix it, let me know and I'll add back in.

    Disclaimers and download

    The code is provided as is. No fees and no guarantees. Also: let me know if I violated any copyrights.

    MouseSupport is a decorator which is used to add mouse events to Silverlight controls.It has been tested on Microsoft Internet Explorer 7 and Firefox versions 2 and 3.
    Known issues/restrictions:

    • When switching to full screen Silverlight, the mouse wheel events are no longer being send to the control.
    • The MouseWheel event is NOT a routed event. To catch the MouseWheel event on a parent decorate the parent with its own MouseSupport decorator.
    • The MouseSupport decorator has several properties like Background, BorderBrush etc. that should not be used, the control should remain UI-less.
    • The MouseSupport decorator has a Template property but it can NOT be set.

    Go to the download...

    Some extra's

    I ran into a very nasty 'feature' of Silverlight while making this. Somehow child controls of custom controls could not be referenced in code. I added a solution for this problem to the download. Let's hope Microsoft fixes this soon.

    Somehow my installation of Visual Studio 2008 does no longer support my Mouse Wheel. The IDE does not respond nor do the web browsers that I open for debugging. In particular for this project that was a real pain as you can imagine. Let me know if you know a solution for this problem.

  • Design

    What is the first thing that you think of when you read or hear "Design"?

    • UML
    • Mondriaan
    • Graphic Tablet
    • Architecture
    • Paint.Net
    • Apple
    • Money

    As a true da Vinci (lover of all arts and suffering from the same syndrome) a strange mix of these enters my brain and causes me to stare into a distant future envisioning clean, shiny, single purpose tools and gadgets that make day to day life a breeze.

    The creation of things. From problem to solution, from idea to realization, from sketch to prototype. That is the really hard part.

    As our customers are getting more and more used to "design" hardware and "design" software, our industry of business applications is slowly catching up with all this coolness by slipping in an occasional gradient and animation that gives the applications the extra umpf. Unfortunately we never learned how to use these correctly nor did we learn to come up with new glittering blings so we end up with copying our precious gradient and animation from project to project, doing what we always do: copy the code.

    There are people who know about this stuff. They don't know programming, software patterns, C# or XML but they invent the glitters that make all of us go wooooow!!!

    How do we get both programmers and graphic/user interface designer to work together?

    Please, let's not do the old waterfall trick again: having the artist draw a marvelous prototype and then spend months by having the programmers to recreate it in their favorite programming platform. I bet the customer wants to change the design as soon as he sees it in action so we need an iterative way of designing and implementing.

    One of my favorite industries is been having the same problem for a while now so let's see what we can learn from them: http://www.gamasutra.com/view/feature/1651/the_codeart_divide_how_technical_.php

    It might be hard to read at times, as the article is using very particular terms of graphics and games programming but a couple of things stand out:

    • Those game programming teams are actual software programming teams, not just a bunch of kids that play around. They have budgets, deadlines, customers, requirements, on the side tool development, politics, communication difficulties... they look just like us.
    • Content, art, assets, levels, graphics, etc. are first class citizens of the project. These teams seem to understand that these will drive the customers towards their product. Yes code is important but without the graphics and art there is no product.
    • As much as programmers and graphic designers are different you need some team members that not just understand both worlds but are also respected in both worlds. These are like glue in your team.
    • The process you use needs some sort of pipeline: a way of moving the design assets into the actual software. You can do that by procedures but tools and software can help a great deal by automating that.

    Wouldn't it be great to really integrate UI design like this in our projects? And on a personal note: I would love to play this "Technical Artist"-role in a project.

    At times the game industry is light-years ahead of us...

  • Microsoft Surface

    I was going to buy a new dinner table anyway so: I want this at home, right now!

    The only negative thing about it is the site, which should have been made with Silverlight.

    Link to Microsoft Surface

  • Microsoft Silverlight

    It's official! WPF/E has been named Microsoft Silverlight. (Yet another meaningless name...) 

    Flash, eat your heart out!

    Link to Microsoft Silverlight

  • Microsoft DevDays 2007

    (It has been too long... I am trying to get less clutter and more valuable info in my blog...)

    Last Friday I wrote my biography, a session summary and I sent them accompanied by my portrait to Microsoft as I will be doing a session on the Dutch DevDays[1]

    Windows Vista and Longhorn Server: The Transactional File System

    I am pretty exited about this feature and about giving a session on it as most of the world seems to concentrate on the bling (or should I say: WOW) of Vista whereas at the same time there is a lot of interesting stuff for developers that doesn't get any attention.

    Hope to see you there!

    [1] Microsoft DevDays 2007

  • WPF galore

    From Channel9. If you have .NET 3.0 installed, try the links marked with XBAP. (Thanks Eric!) 

  • Getting Paid

    What a job! Apparently Microsoft is willing to pay[1] people for changing content in the Wikipedia[2]. This could drive Wouter[3] into raising some serious bucks...

    [1] Get paid to contribute to Wikipedia
    [2] Wikipedia
    [3] Wouter

  • Brain Training

    I have been reading a book on Object-Oriented Analysis & Design from O 'Reilly[1]. Now, O 'Reilly publishes books that, in my opinion, are most of the time good reads and contain a lot of in-depth information. This book appears to be different. Actually, it even says so in it's introduction:

    "How can this be a serious programming book?"

    "What's with all the graphics?"

    "Can I actually learn this way?"

    One look at the cover[2] (no familiar animal cover[3]) gave me the shivers: This is not for me!

    Cover

    I persevered. They actually did all the graphic and layout stuff on purpose: they tried to make a book that helps you to learn. Now that caught my attention. I always want to learn about learning and I found some neat markers in the introduction that I would like to summarize here.

    First the principles:

    1. Make it visual.
    2. Use a conversational and personalized style.
    3. Get the learner (reader) to think more deeply.
    4. Get - and keep- the reader's attention.
    5. Touch their emotions.

    Then what they did:

    1. Use pictures.
    2. Use redundancy.
    3. Use emotional content (humor, surprise, interest)
    4. Use a conversational style.
    5. Use activities to be done by the reader.
    6. Use multiple learning styles.
    7. Use both sides of the brain.
    8. Use stories.
    9. Use challenges and questions.
    10. Use the 80/20 rule. Only the things you need are included.

    And here is what we as readers should do:

    1. Slow down. Read, stop and think.
    2. Do the exercises
    3. Read ALL of the content.
    4. Give your brain a little rest after reading.
    5. Drink water. Dehydration decreases cognitive function. (If you do not understand this you should definitely have some water)
    6. Talk about it.
    7. Listen to your brain.
    8. Feel something. Get emotional involved.
    9. Design something. Apply what you have read.

    The content itself is interesting for people that want to learn OO Analysis and Design and know little or nothing about it. But to teachers and writers it's an excellent example of reaching your audience in a different way.

    [1] Object-Oriented Analysis & Design
    [2] Cover
    [3] Animal Covers

  • Triple tagged

    Yesterday when I read Rory's[1] blog and Jason's[2] blog I wondered how long it would take me to get tagged. Tagging is chainmail pressure to reveal 5 private things in your blog that you shouldn't talk about, nobody wants to know about and are just bandwidth eaters.

    Today I found myself tagged by Eric[3], Wouter[4] and Ramon[5]. This could either mean that I am really popular or I am the last when choosing sides for basketball... Anyway here goes:

    1. Arts. I am a bass player. I used to play double bass[6] but although these things are pretty cool to have in your living room, a good one costs a fortune, so now I am confined to playing my electric bassguitar.
       I love playing jazz because on the bass, to me, it is the most exciting and challenging. I prefer to play the oldies but also love the funky basslines of the bassplayers that played with Miles Davis[7].
    2. More Arts. I like to draw. Just black/gray pencil stuff. No colors, I've never liked coloring (my) drawings since I was six years old. Sometimes I consider starting a weekly cartoon on this blog... who knows...
    3. Culture. My two favorite countries are England and Sweden. Sweden because physically I fit right in (tall, blond, blue eyed) and I love the landscape/space. England because I love the language, humor and country side. I guess one of my great, great, great ancestors was a Viking[8] that conquered England and then decided to conquer a bit of The Netherlands as well...
    4. Language. Most people know that I read/write/speak English... <duh> But I also read Technical German! Way back when I was programming a Amstrad Schneider CPC 6128[9] the only magazines (there was no www back then) that were available were in German and although I flunked German (and French as well) badly in school (I still blame the teachers who I was terrified of) technical (computer related) German has but a few secrets for me. And last but not least I read (and speak a little bit) Hebrew[10] (not the modern but the classical Hebrew). Not that I am fluent in it... I have the level of a 3 year old... but I enjoy it very much.
    5. Science. I like math. Especially fractal[11] and chaos theory[12] but most of all geometric construction. E.g.: Draw an angle of 72 degrees while only using a a straightedge and compass[13].

    So... who to tag... I'll take a little time to think of a few (most have been tagged anyway)

    [1] Rory
    [2] Jason
    [3] Eric
    [4] Wouter
    [5] Ramon
    [6] Double bass
    [7] Miles Davis - Kinda blue
    [8] Viking
    [9] Amstrad Schneider CPC 6128
    [10] Classical Hebrew
    [11] Fractals
    [12] Chaos Theory
    [13] Geometric Construction

  • Be one of the first to download Microsoft XNA Game Studio Express 1.0

     

    XNA Logo

    Today Microsoft releases XNA Game Studio Express 1.0 The official link and download page aren't there yet but after digging around I found a link[1].

    Here's the official link[2]

    [1] Microsoft XNA Game Studio Express 1.0

    [2] Microsoft XNA Game Studio Express 1.0

  • More than just Dispose

    In my previous post about using and Dispose[1] I touched lightly on the Garbage Collector. Indeed very lightly, I never mentioned it but Dispose is very much related to the GC.

    Today I found Chris Lyon's Weblog which contains excellent info on the GC, ranging from Dispose to WeakReferences. Read the blog, it's just 17 posts but well worth your time!

    [1] Using Dispose Close and Connections
    [2] Chris Lyon's WebLog

  • Visual Studio 400 Differences

    I just have to admire the effort they took to promote Visual Studio 2005.

    I really like #144, #156 and #195 videos.

    Link to Visual Studio 400 Differences

  • Using, Dispose, Close and Connections

    Please note that my explanation in this post is incorrect. I am sorry if I caused any trouble.

    In .NET 2.0 disposing the SqlConnection DOES return the connection into the connectionpool.

    In my experience .NET 1.1 acted differently; I will try to investigate this and let you know.

     

    In many talks, tutorials and books you will find C# code that explains the use of using like this:

    using(SqlConnection connection = new SqlConnection(connectionString))
    {
      ...
    }

    Whenever and however execution leaves this using block (power outage disregarded) the connection will be closed because when leaving a using block the Dispose method will be called on the connection object.

    The MSDN states[1]:

    SqlConnection.Dispose Method

    Releases the resources used by the SqlConnection.

    And poses this example:

    public void SqlConnectionHereAndGone()
    {
      SqlConnection myConnection = new SqlConnection("...");
      myConnection.Open();

      //Calling Dispose also calls SqlConnection.Close.
     
    myConnection.Dispose(); }

    All this leads many developers to think that it doesn't matter whether you call Dispose or Close.

    BUT IT DOES!

    Dispose looks like this (thanks to Reflector[2]):

    protected override void Dispose(bool disposing)
    {
          if (disposing)
          {
                this._userConnectionOptions = null;
                this._poolGroup = null;
                this.Close();
          }
          this.DisposeMe(disposing);
          base.Dispose(disposing);
    }

    Yes it calls Close but: it also calls base.Dispose which releases all claimed resources INCLUDING the unmanaged resources that keep the connection in the connection pool alive.

    Lessons to be learned:

    1. Use Close and Dispose depending on the situation.
    2. Do NOT explain the using keyword by using an example that shows a DbConnection.

    It's great to be a trainer and a geek[3].

    [1] SqlConnection.Dispose
    [2] Reflector
    [3] Geek

More Posts Next page »
Powered by Community Server, by Telligent Systems