Search
Thursday, November 20, 2008 ..:: Blendblog.net ::.. Register  Login
 Bloggers Minimize

 Print   
 Sponsors Minimize

 Print   
 Users Online Minimize
Membership Membership:
Latest New User Latest: areel
New Today New Today: 0
New Yesterday New Yesterday: 0
User Count Overall: 15

People Online People Online:
Visitors Visitors: 0
Members Members: 0
Total Total: 0

Online Now Online Now:

 Print   
 Welcome to blendblog.net! Minimize

If you are a developer or designer who is creating cutting edge user interface experiences using Microsoft Expression Blend you've just found a great resource!  The purpose of this site is to share our experience with this brand new product.  As with any new piece of software there is a ton to discover.  Bugs will be revealed and workarounds discovered, hopefully this can be a resource to share in the discovery process!

While this site will focus largely on Expression Blend, it will also encompass WPF, Visual Studio, Silverlight, and other .net 3.5 technologies as they relate to the creation of great software.

Please login using your Microsoft LiveID or register a new account.  Doing so will let you comment on any of the blog entries on the site.  We look forward to helping you in your endeavors as well as you helping others in theirs!  We'd love to have more bloggers on our site...if you are interested please register and contact us!


 Print   
 Adventures in Multibinding Minimize
Location: BlogsSean Cullinan    
Posted by: Sean Cullinan 1/30/2008 8:12 PM
Today I got to play around with multibinding as I build a significant part of my application.  My listboxitem template contains an image that needs to change based on up to 4 different text fields on the underlying data object.  Multibinding works perfectly in this sort of situation.  I was unable to do this through the blend GUI but I was able to do it in the XAML straight away.  Here's how.
First you have to build a class than inherits IMultiValueConverter.  Here's an example of one:
Option Strict On
Imports System.Windows.Data
Public Class ImageSourceConverter
    Implements IMultiValueConverter
    Public Function Convert(ByVal values() As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IMultiValueConverter.Convert
        If Not values Is Nothing Then
            If values.GetUpperBound(0) > 0 Then ' there should always be 2 values at least
                Dim strPath As String = ""
                Dim bBooleanCondition As Boolean = False
                If values.GetUpperBound(0) >= 2 Then
                    strPath = CStr(values(2))
                End If
                If values.GetUpperBound(0) >= 3 Then
                    bBooleanCondition = CBool(values(3))
                End If
                Dim objImagePaths As New ImagePaths
               ' this class returns a path to the image in the format of "pack://application:,,,/myApp;component/Images/myApp.gif" based on the parameters fed in from here...this is an easy class to write
                Dim strImagePath As String = objImagePaths.GetPathFromObjectInfo(Cint(values(0)), CInt(values(1)), strPath, bBooleanCondition)
                objImagePaths = Nothing
                Dim sourceConverter As New ImageSourceConverter
                Return sourceConverter.ConvertFromString(strImagePath)
            End If
        End If
    End Function
    Public Function ConvertBack(ByVal value As Object, ByVal targetTypes() As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object() Implements System.Windows.Data.IMultiValueConverter.ConvertBack
        'todo: implement
    End Function
End Class
Note that unlike a single binding path where .net converts the imagesource from a string automatically, this doesn't work with multibinding paths.  I think this is a bug in the framework.  Anyhow the solution is easy, just do the conversion in your code as I've done here.
The second part is to create the converter resource in your XAML.  First, make sure you have the namespace referenced in the root node of your XAML:
xmlns:util="clr-namespace:myApp;assembly=myApp"
Then create your reference under your Window.Resources (or in my case it was UserControl.Resources) section:
<util:ImageSourceConverter x:Key="FieldsToImageSourceConverter" />
Now in your datatemplate under your image remove any source attribute form the Image tag and beneath the Image tab put the following XAML:
<Image.Source>
     <MultiBinding Converter="{StaticResource FieldsToImageSourceConverter" Mode="Default">
          <Binding XPath="Field1" />
          <Binding XPath="Field2" />
          <Binding XPath="Field3" />
     </MultiBinding>
</Image.Source>
                   
Note I am using XPath because my datasource is an xml document...if you are using a non xml document I believe you would just use <Binding Path="Field1" /> etc.  I first had Path and was getting an error because the values array contained objects of "MS.Internal Object" instead of what I was expecting.

Now, when this template is applied and the data is bound your ImageSourceConverter code is called and can choose the proper image file to return for the source of your image control. 

The only gotcha I've seen is that there appears to be a bug in the Cider designer in VS 2008 if you have multibinding on a form (in my case a usercontrol).  It won't render the control visibly anymore.  I now have the following error when load my control in the visual designer:
 Coversion from type

Blend's designer still seems to work though so I'm not too concerned with this right now.  Although MSFT should look at fixing this ASAP.

I hope this helps someone else out there looking to do multibinding...it is a very cool implementation that IMO is much more elegant than the "itemDataBound" methodologies I'd use in the past with ASP.net.
 
Permalink |  Trackback

Comments (2)   Add Comment
Re: Adventures in Multibinding    By Graham Dyson on 2/11/2008 7:29 AM
Hi Sean,<br><br>I was just using the Multibinding class myself last night to allow for multiple bindings to a set of checkboxes and their enabled properties. <br><br>I got a similar problem to yours regarding the designer, but managed to fix it. I think your exception will be firing when you cast the elements in the values array as String, at design time it appears to be of the type NamedObject.

Re: Adventures in Multibinding    By stiphy31 on 2/12/2008 11:16 AM
Graham,<br><br>You are correct. I added the following after the "If values.GetUpperBound(0) > 0" statement:<br>If Not values(0).GetType Is GetType(String) Then ' prevents ide error<br> Return Nothing<br>End If<br>and the IDE problem is fixed.<br><br>Thanks for the fix!<br><br>Sean


Your name:
Title:
Comment:
Add Comment   Cancel 

  
 Search Minimize

 Print   
 Archive Minimize

 Print   
 Blendblog Survey Minimize
Our next client application will be written using:




Submit Survey  View Results

 Print   
Copyright 2008 by blendblog.net   Terms Of Use  Privacy Statement
DotNetNuke® is copyright 2002-2008 by DotNetNuke Corporation