Binding Template Property to an Image

3 posts, 1 answers
  1. Reid
    Reid avatar
    317 posts
    Member since:
    Oct 2008

    Posted 20 Jun 2014 Link to this post

    Hello,

    We have a control that contains a RadCarousel that gets it's DataContext/ItemSource set to a View Model property which is an ObservableCollection<Tool> of custom "Tools" objects.  That object has a Name property and an Image property.  In it's previous life in a generic legacy WPF solution the control data bound the icon/image to display using an "ImagePath" data member.  This worked fine because the control was able to access images set to Resource as the build type and located in a /Resources folder.

    The current project is a Prism 4 solution and contains multiple modules.  Each module is loaded dynamically from a folder at runtime using the DirectoryModuleCatalog class.  This is all working fine and each module injects it's own RibbonGroup into a RadRibbonView,  The Home RibbonGroup contains this RadCarousel control mentioned above.  Each module injects it's own "Tool" into the hosted view model using an event.  This is working fine in that the RadCarousel is displaying the tools but is currently only displaying a name property.  The DataTemplate binds the "Name" and "Image" data members but again the image is not showing.

    The Tool class has an "ImageTool" property (of type System.Drawing.Image)  that is filled by the Module classes before the Home Ribbon shows.  So by the time the Home Ribbon view shows it has a valid ItemSource filled with these Tool objects and their respective ToolImages property containing an instantiated image.  I felt it had to be done this way because the "ImagePath" design or property in it's previous life is now obsolete in that there cannot be a static path pointed to in this Prism paradigm where the host project is loading these modules dynamically and from a folder.

    Here is the DataTemplate code that is working but not showing an image ..


    <DataTemplate x:Key="customItemTemplate">
                    <Grid HorizontalAlignment="Center">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="*"/>
                        </Grid.RowDefinitions>                    
                        <Image  Source="{Binding ToolIimage}" Width="25" Height="25" Grid.Row="0"/>
                        <TextBlock Text="{Binding Name}" Grid.Row="1" />
                    </Grid>
                </DataTemplate>

    Can someone offer a suggestion as to how to get an image displaying for each item in the Carousel from an instantiated image?

    Thank you,

    Reid


  2. Answer
    Lance | Tech Support Engineer, Sr.
    Admin
    Lance | Tech Support Engineer, Sr. avatar
    138 posts

    Posted 23 Jun 2014 Link to this post

    Hi Reid,

    Since ImageTool is of type System.Drawing.Image, you can't directly bind it to the Source property of an Image control in XAML. What you can do is use a ValueConverter.

    This StackOverflow post has a great example of a converter that takes the incoming System.Drawing.Image value and converts it to a BitmapImage that your DataTemplate's Image control can use.

    Using your code, it would look like this...

    public class ImageConverter : IValueConverter
    {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                if (value == null)
                       return null;
     
                //Your incoming ToolImage object
                var image = (System.Drawing.Image)value;
     
                //new-up a BitmapImage
                var bitmap = new System.Windows.Media.Imaging.BitmapImage();
                bitmap.BeginInit();
     
                //stream image info from Image to BitmapImage
                MemoryStream memoryStream = new MemoryStream();
                image.Save(memoryStream, ImageFormat.Bmp);
                memoryStream.Seek(0, System.IO.SeekOrigin.Begin);
                bitmap.StreamSource = memoryStream;
                bitmap.EndInit();
     
                //return the BitmapImage that you can bind to the XAML
                return bitmap;
            }
     
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                return null;
            }
        }


    Now make the converter available as a StaticResource. Which would look like this...

    <Window.Resources>
         <namespaceWhereTheConverterIs:ImageConverter x:Key="MyImageConverter />
    </Window.Resources>


    Then finally you do this for your DataTemplate...

    <DataTemplate x:Key="customItemTemplate">
               <Grid HorizontalAlignment="Center">
                         <Grid.RowDefinitions>
                             <RowDefinition Height="*"/>
                             <RowDefinition Height="*"/>
                         </Grid.RowDefinitions>                   
                         <Image  Source="{Binding ToolIimage, Converter="{StaticResource MyImageConverter}" Width="25" Height="25" Grid.Row="0"/>
                         <TextBlock Text="{Binding Name}" Grid.Row="1" />
               </Grid>
    </DataTemplate>


    This should have you up and running. Thank you for contacting Support and thank you for choosing Telerik.

    Regards,
    Lance
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
  3. UI for WPF is Visual Studio 2017 Ready
  4. Reid
    Reid avatar
    317 posts
    Member since:
    Oct 2008

    Posted 23 Jun 2014 in reply to Lance | Tech Support Engineer, Sr. Link to this post

    Hello Lance,

    Thank you very much for the fast and precise response.  Much appreciated!

    Reid
Back to Top