1

I'm trying to bind images in a ListView via code behind. The goal is to write this section of code in C #. How does binding in code behind work? This is my xaml code:

<ListView x:FieldModifier="public" x:Name="MyListView" HorizontalAlignment="Left" VerticalAlignment="Top" ItemsSource="{Binding ListViewDataList}">
    <ListView.View>
        <GridView x:Uid="GridViewTest">
            <GridViewColumn Header="Column1" DisplayMemberBinding="{Binding Column1Text}"/>
            <GridViewColumn Header="Column2">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <Image Width="50" Height="50" Source="{Binding Column2Img}"/>
                        </StackPanel>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

Column1Text and Column2Img are properties. I tried something like this:

GridView MyGridView = new GridView();

GridViewColumn gvc1 = new GridViewColumn();
gvc1.DisplayMemberBinding = new Binding("Column1Text");
gvc1.Header = "Column1";
MyGridView.Columns.Add(gvc1);

System.Windows.Controls.Image img = new System.Windows.Controls.Image();
img.Height = 50;
img.Width = 50;
img.Source = new Binding("Column2Img");

FrameworkElementFactory spFactory = new FrameworkElementFactory(typeof(StackPanel));
spFactory.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);
DataTemplate dt = new DataTemplate();
dt.VisualTree = spFactory;

GridViewColumn gvc2 = new GridViewColumn();
gvc2.Header = "Column2";
gvc2.CellTemplate = dt;
MyGridView.Columns.Add(gvc2);

MyListView.View = MyGridView;

But the binding for image in code behind doesn't work.

mm8
  • 163,881
  • 10
  • 57
  • 88
sanjar14
  • 47
  • 1
  • 10
  • Use a Converter on your Binding and you should be fine. But what your Image is? string, byte[], ImageSource, Bitmap? [byte example](https://stackoverflow.com/a/9564425/2029607). – XAMlMAX Feb 07 '18 at 13:55
  • @XAMlMAX image is type of string. – sanjar14 Feb 07 '18 at 14:01

1 Answers1

1

You should bind the Source property instead of setting it to a Binding object directly:

img.SetBinding(Image.SourceProperty, new Binding("Column2Img"));

But you also need to create an FrameworkElementFactory for the Image element that you add to spFactory:

FrameworkElementFactory imgFactory = new FrameworkElementFactory(typeof(Image));
imgFactory.SetValue(Image.HeightProperty, 50.0);
imgFactory.SetValue(Image.WidthProperty, 50.0);
imgFactory.SetBinding(Image.SourceProperty, new Binding("Column2Img"));

FrameworkElementFactory spFactory = new FrameworkElementFactory(typeof(StackPanel));
spFactory.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);
spFactory.AppendChild(imgFactory);

Note that using a FrameworkElementFactory is a deprecated way to programmatically create templates though: https://msdn.microsoft.com/en-us/library/system.windows.frameworkelementfactory(v=vs.110).aspx.

The recommended way to programmatically create a template is to load XAML from a string or a memory stream using the Load method of the XamlReader class.

mm8
  • 163,881
  • 10
  • 57
  • 88
  • Thand you! I got an exception: "50" is not a valid value for property "Height" in imgFactory.SetValue(Image.HeightProperty, 50); – sanjar14 Feb 07 '18 at 15:05
  • 1
    Change it to 50.0 or 50d to indicate that it's a double value. I edited my answer. – mm8 Feb 07 '18 at 15:07
  • the solution with xaml code shows the images in the listview as expected. but not the one with code behind. I create the listview with c# in loaded event of the window.The first column contains the string, as expected, but not the second. Only the type of the binding value can be seen as a string. – sanjar14 Feb 07 '18 at 15:44
  • Ok solved. I forgot the line "gvc2.CellTemplate = dt;" – sanjar14 Feb 07 '18 at 15:52