Question

I need you to help me with a problem I am experiencing with. I have a single listbox that is supposed to display a Car Detials (right side) and Car Image (left side) after retrieving them from the database. Note: convert byte into images from database which is working fine. Problem is that the images dont display in the listbox (left side) but only Car Details displayed. Missing Images! I make sure Car and CarImage in WPF style to binding. No idea what I have done wrong in my code or wpf style. I would much aprreciate if you are willing to take a look at my codes what is problem. Your help much appreciated. Thanks!

WPF:

 <ListBox Style="{DynamicResource ListBoxStyle1}"  DisplayMemberPath="Car" X:Name="listboxCars"  />

WPF Style - Car Information (right side) and Car Image (left side):

    <DataTemplate x:Key="templateListBoxItem">
    <Grid Margin="5">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"></ColumnDefinition>
            <ColumnDefinition Width="*"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <Border Grid.Column="0"
            Grid.Row="0"
            Grid.RowSpan="2"
            Margin="0,0,10,0">
            <!-- binding it to Car Image from database -->
            <Image Source="{Binding Path=CarImage}"  
               Stretch="Fill"
               Height="40"
               Width="40"></Image>
        </Border>
        <!-- same here to binding to Car -->
        <TextBlock Text="{Binding Path=Car}"
               FontWeight="Bold"
               Grid.Column="1"
               Grid.Row="0"></TextBlock>
    </Grid>
</DataTemplate>

<Style x:Key="ListBoxStyle1" TargetType="{x:Type ListBox}">
    <Setter Property="ItemTemplate" Value="{StaticResource ResourceKey=templateListBoxItem}"></Setter>

</Style>

This method to retrieve a list of Car Informations with its own Images from database

public List<CarInfo> GetCarImagesList (int days)
{

 Cars = new List<CarInfo>();
 const string sqlQuery = "select Car, CarImage from CarTemplates where Days = @days order by Car asc";

            using (var command = new SqlCommand(sqlQuery, sqlConn))
            {
                try
                {
                    command.CommandType = CommandType.Text;
                    command.Parameters.AddWithValue("@days", days);

                    using (var reader = command.ExecuteReader())
                    {

                        while (reader.Read())
                        {
                            byte[] buffer = new byte[10000];
                            var car = new CarInfo
                            {
                                Car = reader["Car"].ToString()                                                                        
                            };
                            if (!reader.IsDBNull(reader.GetOrdinal("CarImage")))
                            {
                                long size = reader.GetBytes(reader.GetOrdinal("CarImage"), 0, buffer, 0, 10000);
                                using (MemoryStream strm = new MemoryStream())
                                {
                                    strm.Write(buffer, 0, (int) size);
                                    strm.Position = 0;
                                    System.Drawing.Image img = System.Drawing.Image.FromStream(strm);
                                    car.CarImage = img;
                                }
                            }
                            Cars.Add(car);
                        }
                    }
             .
             .
             .
           return Cars;
    }

Last thing: when you click the button, the listbox will display CarInformation (right side) and CarImage (left side). In runtime I check that there is a list of CarInformations and CarImages in _databaseCarList. There is even value (byte) of Images (list.CarImage) but why dont images display?

        private void Button1_Click(object sender, SelectionChangedEventArgs e)
    {
        _carImageList = new CarImageExtractor();
        const int oneDay = 1;
        var lstCar = new List<CarInfo>();

            _databaseCarList = new ObservableCollection<CarInfo>(_carImageList.GetCarImagesList(oneDay));

            if (_databaseCarList != null)
            {
                foreach (var list in _databaseCarList)
                {

                    lstCar.Add(new CarInfo{Car = list.Car, CarImage = list.CarImage});
                }

                listboxCars.ItemsSource = lstCar;

            }

    }
Was it helpful?

Solution

You are using a WindowsForms image (System.Drawing.Image) that is not support by WPF as ImageSource for the Image. (When debugging in VisualStudio you should get binding errors from ImageSourceConverter)

For WPF you need to use BitmapImage.

Change your property CarImage to type System.Windows.Media.Imaging.BitmapImage and change the initialization code of your image to the following.

strm.Write(buffer, 0, (int) size);
strm.Position = 0;

BitmapImage img = new BitmapImage();
img.BeginInit();
img.StreamSource= strm;
img.EndInit();

car.CarImage = img;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top