Dynamically Added Image to WrapPanel in WPF

1.5k views Asked by At

Added Image Controls to WPF WrapPanel from a list of images defined in xml. Everything seems to be in place. I even inspected in debug but nothing is visual. Is there a step I am missing?

        _printImages.ReadXml(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Images.xml"));

        if (_printImages.Tables.Contains("image") && _printImages.Tables["image"].Rows.Count > 0)
        {

            foreach (DataRow row in _printImages.Tables["image"].Rows)
            {
                // build info object
                ImageInfo imgInfo = new ImageInfo();

                imgInfo.Source = row["Source"].ToString();
                imgInfo.Custom = bool.Parse(row["Custom"].ToString());
                imgInfo.Font = row["Font"].ToString();
                imgInfo.FontSize = int.Parse(row["FontSize"].ToString());
                imgInfo.CharacterLimit = int.Parse(row["Characterlimit"].ToString());
                imgInfo.CustomType = row["Customtype"].ToString();

                _images.Add(imgInfo);

                //create control
                Image imgControl = new Image();
                BitmapImage imgFile = new BitmapImage();

                try
                {
                    imgFile.BeginInit();
                    imgFile.StreamSource = new FileStream(imgInfo.Source, FileMode.Open);
                    imgControl.Source = imgFile;
                    imgControl.Tag = _images.Count - 1;
                    imgControl.Height = Properties.Settings.Default.ImageHeight;
                    imgControl.Width = Properties.Settings.Default.ImageWidth;
                    imgControl.MouseDown += new MouseButtonEventHandler(image_MouseDown);
                    imgControl.Visibility = System.Windows.Visibility.Visible;
                    imageSelectionPanel.Children.Add(imgControl);
                }

                catch (System.Exception ex)
                {
                    MessageBox.Show(ex.Message.ToString(), "Unable to create image");
                }


            }
        }
1

There are 1 answers

0
Clemens On BEST ANSWER

Your code is missing an EndInit call after setting the StreamSource property of the BitmapImage.

Moreover, the stream should be closed after loading the bitmap, which is usually done by a using block and which also requires to set BitmapCacheOption.OnLoad:

using (var stream = new FileStream(imgInfo.Source, FileMode.Open))
{
    imgFile.BeginInit();
    imgFile.StreamSource = stream;
    imgFile.CacheOption = BitmapCacheOption.OnLoad;
    imgFile.EndInit();
}

Alternatively, the BitmapImages could also be loaded directly from the image file paths without using a FileStream:

var imgFile = new BitmapImage(new Uri(imgInfo.Source, UriKind.RelativeOrAbsolute));

You might also create a view model with a collection of ImageInfo objects and bind an ItemsControl to this collection. The ItemsControl would have the WrapPanel as its ItemsPanel, and an ItemTemplate with the Image control:

<ItemsControl ItemsSource="{Binding ImageInfos}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Image Source="{Binding Source}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

See the Data Templating Overview article on MSDN for details.