Confessions of a .NET Developer!

How to convert bytes to BitmapImage WPF

In this short post I will explain how convert array of bytes to BitmapImage in WPF ofcourse. I happened to use it when I needed to display Images in a DataGrid. And that Image is stored in a column named LargePhoto of data type VARBINARY(MAX) in AdventureWorksDW2008 Database. The VARBINARY(MAX) actually gets transformed into byte[] after mapping the Database to Entity Framework(ya of type EDMX). So I created a Converter to convert the bytes to BitmapImage.

There is one link I found which works in case of Silverlight, haven’t tried in WPF: Byte to BitmapImage in Silverlight

This one by Jobi Joy at StackOverflow also works: Byte to BitmapImage in WPF
But the problem is that stream is left open after conversion, which seems to me is not correct.
In the above case, the stream can be closed using this:

image.StreamSource.Dispose();

Okay so below is the code which will return a BitmapImage when a byte[] is given.

private BitmapImage GetBitmapImageFromBytes(byte[] bytes)
{   
   BitmapImage btm;
   using (MemoryStream ms = new MemoryStream(bytes))
   {
      btm = new BitmapImage();
      btm.BeginInit();
      btm.StreamSource = ms;
      // Below code for caching is crucial.
      btm.CacheOption = BitmapCacheOption.OnLoad;
      btm.EndInit();
      btm.Freeze();
   }
   return btm;
}

This line:

btm.CacheOption = BitmapCacheOption.OnLoad;

is very important. It says that the Image will be loaded into memory, and each request for the Image will be fetched from that memory store. So after closing or disposing the memory stream, the Image will be available in the memory cache.

I also found this piece of code written by Kent Boogart in CodePlex done in a different and in a better way but serving the same purpose : Byte to BitmapImage in WPF (By Kent Boogart)

Hope this helps! Thanks for reading! 🙂

Advertisements

December 25, 2011 Posted by | C Sharp, WPF | 1 Comment

Auto-fixing height and width of Button in WPF DataGrid

This short post will explain how to automatically fix the height and width of a Button in WPF DataGrid.
The idea is to take the height and width of the cell containing the button. To set a proper margin, we can reduce both the parameters by using a converter.
First the DataGrid:

        <DataGrid VerticalContentAlignment="Center"
                  RowHeight="50" ColumnWidth="*"                  
                  ItemsSource="{Binding Path=Persons}" 
                  IsReadOnly="True"
                  AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="First Name" Binding="{Binding Path=FirstName}"/>
                <DataGridTextColumn Header="Last Name" Binding="{Binding Path=LastName}"/>
                <DataGridTextColumn Header="Address" Binding="{Binding Path=Address}"/>
                <DataGridTemplateColumn Header="Select">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Button Content="Select"
                                    Height="{Binding RelativeSource={RelativeSource AncestorType=DataGridCell}, Path=ActualHeight}"
                                    Width="{Binding RelativeSource={RelativeSource AncestorType=DataGridCell}, Path=ActualWidth}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>

Lets take a close look at the “Select” column. Its a DataGridTemplateColumn with each row having a Select button. The Button’s height and width is provided by its visual container DatGridCell using the RelativeSource Binding.
It will look something like this:
With no converter

But it doesn’t look good, what’s required is to provide margin. Simply giving margin won’t help.
A converter will be required here to reduce the height and width of the button. On further research, I figured out that a combination of converter and margin can solve the issue, but its still quite unclear to me how it works.

Here is the converter that is used:

    class HeightWidthFixerConverter : IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (parameter != null && value != null)
            {
                double reduceBy;
                if (double.TryParse(parameter.ToString(), out reduceBy))
                    return (double)value - reduceBy;
            }
            return value;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion
    }

The ConverterParameter will be used to specify how much height or width you want to reduce by.
The CellTemplate for the DataGrid will look something like this:
Here is the resource key for converter:

    <Window.Resources>
        <converter:HeightWidthFixerConverter x:Key="heightWidthFixer"/>
    </Window.Resources>

And the CellTemplate:

                <DataGridTemplateColumn Header="Select">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Button Content="Select"
                                    Margin="2"
                                    Height="{Binding RelativeSource={RelativeSource AncestorType=DataGridCell}, Path=ActualHeight, Converter={StaticResource heightWidthFixer}, ConverterParameter=10}"
                                    Width="{Binding RelativeSource={RelativeSource AncestorType=DataGridCell}, Path=ActualWidth, Converter={StaticResource heightWidthFixer}, ConverterParameter=7}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

The height and width has been reduced by 10 & 7 respectively.
The DataGrid will look like something like this:

With Converter

With Converter

It looks fine now, properly spaced. Surely this hack is not the finest, so I would like to hear your thoughts and suggestions for improvement. Somehow I feel there must be some better way to do this, until then I shall use this. Thank you for reading and have a nice day!

December 20, 2011 Posted by | WPF | 4 Comments

How to enlarge or re-size Calendar in WPF DatePicker

It has been a long time since my last post!
Okay so in this short article, I will show you how to increase the size of a calendar in WPF 4.0 DatePicker. Since I’m currently working on a touchscreen application, it required me to create a larger calendar so that the user can touch it.
So as usual, like normal developers, I started googling for answers, but it was unsuccessful(maybe I need to improve my googling skills!). It required me to think a little more, but finally I got the solution! This is how I did:
You can edit the template of the calendar by wrapping it in a ViewBox. So now the calendar will fit according to the size of the ViewBox. Simples!

Here is the Style for the calendar:

        <Style x:Key="styleCalendar" TargetType="{x:Type Calendar}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Calendar}">
                        <!-- Wrapping in ViewBox will enlarge calendar of that size.-->
                        <Viewbox Height="400"
                                 Width="400">
                            <CalendarItem x:Name="PART_CalendarItem"
                                          Background="{TemplateBinding Background}"
                                          BorderBrush="{TemplateBinding BorderBrush}"
                                          BorderThickness="{TemplateBinding BorderThickness}"/>
                        </Viewbox>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

And apply the style to the DatePicker:

        <DatePicker CalendarStyle="{StaticResource styleCalendar}" Height="25" HorizontalAlignment="Left" Name="datePicker1" Width="115" />

It will look something like this:

Re-size Calendar

Calendar Re-sized

Cool!
I hope it helped, do leave your comments or suggestions for further improvements.

Happy coding! 🙂

December 19, 2011 Posted by | C Sharp, WPF | 25 Comments