Announcement

Collapse
No announcement yet.

[WPF] ImageSource Binding in DataGrid

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • [WPF] ImageSource Binding in DataGrid

    Hi,

    Ich habe eine Liste mit Artikeln, die ich über eine DataTable an mein DataGrid binde.
    Das DataGrid sieht gekürzt so aus:
    HTML Code:
        <Window.Resources>
            <local:ArticleImageConverter x:Key="ImageConverter"/>
        </Window.Resources>
    
    ...
    
    <DataGrid Grid.Row="0" Name="gridArticles"
            ItemsSource="{Binding}"
            RowHeaderWidth="0"
            AutoGenerateColumns="False"
            SelectionMode="Single"
            SelectionUnit="FullRow"
            AlternatingRowBackground="#eee"
            FontSize="16"
            CanUserAddRows="False"
            HorizontalGridLinesBrush="#ccc"
            VerticalGridLinesBrush="#ccc">
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="Artikelnummer" Width="Auto">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="*"/>
                                <RowDefinition Height="*"/>
                            </Grid.RowDefinitions>
                            <TextBlock Grid.Row="0" Text="{Binding Path=SKU}"/>
                            <TextBlock Grid.Row="1" Text="{Binding Path=EAN}" FontSize="10" Foreground="#aaa"/>
                        </Grid>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTemplateColumn Header="Bezeichnung" Width="*">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="*"/>
                                <RowDefinition Height="*"/>
                            </Grid.RowDefinitions>
                            <TextBlock Grid.Row="0" Text="{Binding Path=Bezeichnung}" TextWrapping="Wrap"/>
                            <TextBlock Grid.Row="1" Text="{Binding Path=Variante}" TextWrapping="NoWrap" FontSize="14" Foreground="#39c"/>
                        </Grid>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTemplateColumn Header="Bild" IsReadOnly="True">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Image Source="{Binding Path=ImagePath, Converter={StaticResource ImageConverter}}" Width="50" Height="50"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTextColumn Header="Typ" Width="35" Binding="{Binding Path=Typ}"/>
        </DataGrid.Columns>
    </DataGrid>
    Dabei geht es genau gesagt um diese DataColumn:
    HTML Code:
            <DataGridTemplateColumn Header="Bild" IsReadOnly="True">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Image Source="{Binding Path=ImagePath, Converter={StaticResource ImageConverter}}" Width="50" Height="50"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
    Die DataTable ist auf diese Weise gebunden:
    Code:
    using (SqlConnection conn = new SqlConnection(Properties.Resources.SqlConnectionString))
    {
        using ( SqlDataAdapter adp = new SqlDataAdapter(Properties.Resources.SqlLoadAvailableArticlesList, conn) )
        {
            adp.SelectCommand.Parameters.AddWithValue("@mandant", 1);
            adp.SelectCommand.Parameters.AddWithValue("@pricelist", this.PriceList);
            adp.SelectCommand.Parameters.AddWithValue("@discountlist", this.DiscountList);
            adp.Fill(this.MainWindowDataSet, "Articles");
    
            if (this.MainWindowDataSet.Tables["Articles"].Rows.Count < 1)
                return;
    
            // data binding
            this.gridArticles.DataContext = this.MainWindowDataSet.Tables["Articles"];
        }
    }
    Mein Problem ist nun, dass die Bilder als einziges nicht angezeigt werden. Den Fehler vermute ich im ArticleImageConverter, denn ich versuche eine für das Binding gültige ImageSource aus einem String zu convertieren.
    Dazu habe ich folgenden Converter-Aufbau:
    Code:
        [ValueConversion(typeof(System.String), typeof(System.Windows.Media.ImageSource))]
        public class ArticleImageConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                if (value == null)
                    return null;
    
                // converting code
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                return null;
            }
    Nun habe ich verschiedene Herangehensweisen ausprobiert:
    Code:
    ImageSourceConverter converter = new ImageSourceConverter();
    object obj = converter.ConvertFromString((string)value);
    
    return (ImageSource)obj;
    Code:
    BitmapImage bitmap = new BitmapImage(new Uri((string)value));
    return bitmap;
    Code:
    System.Drawing.Image image = System.Drawing.Image.FromFile((string)value);
    BitmapImage bitmap = new BitmapImage();
    
    bitmap.BeginInit();
    MemoryStream memoryStream = new MemoryStream();
    image.Save(memoryStream, ImageFormat.Jpeg);
    memoryStream.Seek(0, SeekOrigin.Begin);
    bitmap.StreamSource = memoryStream;
    bitmap.EndInit();
    
    return bitmap;
    Letzteres soll angeblich lt. einem Tutorial funktionieren, bei mir scheint er aber gar nicht in den Converter zu springen, denn wenn ich einen BreakPoint innerhalb des Converters setze, kommt er dort nie an.

    Wer schubst mich bitte mal in die richtige Richtung?
    Danke
    Zuletzt editiert von Arne Drews; 11.05.2019, 23:19.
    PHP rocks!
    Eine Initiative der PHP Community

  • #2
    Ok, klassischer Fall von: Warum nicht gleich richtig...

    Ich hatte eine falsche Source im XAML angegeben. Man benötigt an der Stelle nicht mal einen ValueConverter. Das Source-Attribut kann direkt mit einer URL umgehen:
    HTML Code:
    <DataGridTemplateColumn Header="Bild" IsReadOnly="True">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <Image Source="{Binding Path=ImgPath}" Width="50" Height="50"/>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
    Alle Bilder werden wie erwartet angezeigt.

    Gruß Arne
    PHP rocks!
    Eine Initiative der PHP Community

    Comment

    Working...
    X