0

Good day all, I am trying to make a application so that I can do some basic edits on photos. I have binded a collection to a listbox and I can get all my text information to populate but I cant get my image to show. Every example that I see sets the image by using a uri, however, I didn't do that to create my image and I'm not sure if that is why. I do know that the image appears to be loaded correctly as all the properties about the image are shown (height width pixals). I believe I deleted all the code not related to the issue.

Thanks in advance, Chris

XML

<!--Step 1-->
        <GroupBox x:Name="Step1">
            <Grid>
                <StackPanel>
                    <Label>Select Pictures</Label>
                    <ListBox x:Name="PictureNames" ItemsSource="{Binding}" Height="auto">
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Horizontal">
                                    <Image x:Name="CurrentPhoto" Width="300" Height="200" Source="{Binding CurrentPhoto}"/>
                                    <!--old code trying to make this work  <Canvas x:Name="CurrentPhoto" Width="300" Height="200" Background="{Binding CurrentPhoto}"/>-->
                                    <TextBlock x:Name="Name" Text="{Binding Path=Name}"></TextBlock>
                                </StackPanel>
                            </DataTemplate>
                        </ListBox.ItemTemplate>

                    </ListBox>
                    <Button x:Name="AddPicture" Click="AddPicture_Click">Click to upload Pictures</Button>
                </StackPanel>
            </Grid>
        </GroupBox>

CODE

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Win32;
using System.Collections.ObjectModel;

namespace S2IPictureWatermarker
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{

    ObservableCollection<picture> Pictures;
    Position ThisStep = new Position();
    public MainWindow()
    {
        InitializeComponent();
        Startup();

    }

    private void Startup()
    {
        ThisStep.CurrentStep = 1;
        Pictures = new ObservableCollection<picture>();
        Step1.Visibility = System.Windows.Visibility.Visible;
        Step2.Visibility = System.Windows.Visibility.Collapsed;
        Step3.Visibility = System.Windows.Visibility.Collapsed;
        Step4.Visibility = System.Windows.Visibility.Collapsed;
    }

    //GroupEditLstBx.ItemsSource = SelectedPhotos

    private void AddPicture_Click(object sender, RoutedEventArgs e)
    {//add picture to list of pictures
        //get photo(s) location
        OpenFileDialog openFileDialog1 = new OpenFileDialog();
        InitializeOpenFileDialog(openFileDialog1);
        Nullable<bool> result = openFileDialog1.ShowDialog();
        //if photos are found, add to collection
        if (result == true)
            CreatePictureCollection(openFileDialog1.FileNames);
    }

    private void CreatePictureCollection(string[] FullPathNames)
    {
        foreach (string pathName in FullPathNames)
        {
            picture newPicture = new picture();
            newPicture.NewPicture(pathName);
            if(Pictures.Count >= 1)
            {//dont do anything
            }
            else
            {
                PictureNames.ItemsSource = Pictures;
            }
            Pictures.Add(newPicture);

        }
    }

    private void InitializeOpenFileDialog(OpenFileDialog openFileDialog1)
    {
        // Set the file dialog to filter for graphics files.
        openFileDialog1.Filter =
            "Images (*.BMP;*.JPG;*.GIF)|*.BMP;*.JPG;*.GIF|" +
            "All files (*.*)|*.*";

        //  Allow the user to select multiple images.
        openFileDialog1.Multiselect = true;
        //                   ^  ^  ^  ^  ^  ^  ^

        openFileDialog1.Title = "My Image Browser";

    } 
}
}

CODE FOR picture class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.ComponentModel;

namespace S2IPictureWatermarker
{
    class picture : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private int height;

        public int Height
        {
            get { return height; }
            set { height = value; OnPropertyChanged("Height"); }
        }
        private int width;

        public int Width
        {
            get { return width; }
            set { width = value; OnPropertyChanged("Width"); }
        }

        private string type;

        public string Type
        {
            get { return type; }
            set { type = value; OnPropertyChanged("Type"); }
        }

        private string location;

        public string Location
        {
            get { return location; }
            set { location = value; OnPropertyChanged("Location"); }
        }

        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; OnPropertyChanged("Name"); }
        }

        private int orgHeight;

        public int OrgHeight
        {
            get { return orgHeight; }
            set { orgHeight = value; OnPropertyChanged("OrgHeight"); }
        }

        private int orgWidth;

        public int OrgWidth
        {
            get { return orgWidth; }
            set { orgWidth = value; OnPropertyChanged("OrgWidth"); }
        }

        private Image currentPhoto;

        public Image CurrentPhoto
        {
            get { return currentPhoto; }
            set { currentPhoto = value; OnPropertyChanged("CurrentPhoto"); }
        }

        //methods
        //NEW PICTURE
        public bool NewPicture(string PictureFullPath)
        {
            bool Created = false;
            try
            {
                //set path(location), name, type
                Location =  Path.GetPathRoot(PictureFullPath);                 
                Name= Path.GetFileNameWithoutExtension(PictureFullPath);
                Type = Path.GetExtension(PictureFullPath);


                //set current image
                CurrentPhoto = Image.FromFile(PictureFullPath);
                //set height and width
                Height = CurrentPhoto.Height;
                Width = CurrentPhoto.Width;

                Created = true;
            }
            catch (Exception)
            {

                throw;
            }
            return Created;
        }


        //create the OnPropertyChanged method to raise
        protected void OnPropertyChanged(string changedName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(changedName));
            }
        }
    }
}
chris
  • 78
  • 1
  • 15

2 Answers2

0

I believe you can't put System.Windows.Image in the background of the canvas element. That's because System.Windows.Image is UIElement and can't be used as brush. You can create an ImageBrush from an ImageSource (by Uri) and put it into the background. Or you can create ContentControl instead of your canvas element and put the image from presenter in it.

sedovav
  • 1,986
  • 1
  • 17
  • 28
  • my fault, that line should read I was playing around with different objects to see if I could get it to work. I'm going to try the contentcontrol route now to see if that would work. – chris Jun 26 '13 at 13:56
  • so you need an [System.Windows.Media.ImageSource](http://msdn.microsoft.com/ru-ru/library/system.windows.media.imagesource.aspx) object in the presenter's property. or use a ContentControl instead of the Canvas. – sedovav Jun 26 '13 at 14:01
  • you can [convert file pathes into Uri](http://stackoverflow.com/questions/1546419/convert-file-path-to-a-file-uri), if it's the root of the problem – sedovav Jun 26 '13 at 14:08
  • Now if I create a uri, will it just be the URI for where the orginal file is located? I think this would be a problem as the image I wanted to display will be getting modified as they user progresses through the steps(total 4). On step 1 user selects the picture(s) they want to edit, so I can use the URI that is associated w/ the org pic, but on step 2 they start editing pic by adding watermarks and rotating the pic. If I go this route it sounds like I will have to save a copy of the picture, then set the editable(currentPhoto) image uri to the saved copy. – chris Jun 26 '13 at 14:17
  • it depends on the way you edit the image. but I think the original image file will not be changed until you saved your modifications into it. – sedovav Jun 26 '13 at 14:52
  • It seems like there should be a better way but I am going to try saving copies of the original photos into a temp folder that I will create on the desktop and used the uri of the copied images. I figured this would be best way if I have to go this route so as to not mess with the originals until I'm ready to committee to the changes. – chris Jun 26 '13 at 15:15
  • don't forget to check an answer if it was helpful – sedovav Jun 26 '13 at 18:50
0

Hi try something like this in the canvas element.

<Canvas.Background>
                    <ImageBrush ImageSource="{Binding CurrentPhoto}" Stretch="UniformToFill"></ImageBrush>
</Canvas.Background>

EDIT: If this doesnt work make your property "CurrentPhoto" to an imagebrush.

Tan
  • 2,148
  • 3
  • 33
  • 54
  • I tried it in my code and was not able to see anything as far as an image. were you able to make it work? – chris Jun 26 '13 at 14:47
  • Did you try to make the image to ImageBrush instead of using Image ? – Tan Jun 26 '13 at 14:48
  • Do really have to use canvas ? if not try to use the image element. But if you really want to use the canvas you have to convert the property CurrentPhoto to an imagebrush. – Tan Jun 26 '13 at 14:50
  • No I don't, I changed the code to show I wanted to use image object instead. I was just playing with the code before I posted it to try and see if I could make it work with different object. – chris Jun 26 '13 at 15:01
  • no, it doesn't work, the line I used is in the place of the canvas was no image is displaced – chris Jun 26 '13 at 15:12
  • But the property CurrentPhoto that you use for your binding does it contains something ? – Tan Jun 26 '13 at 15:23
  • it is an object of System.Drawing.Image it does contain an image, I checked the values for the image and the heigh and width values populate after image has been added. – chris Jun 26 '13 at 15:41
  • 1
    System.Drawing.Image and ImageSource (which is what WPF uses) are not compatible. You need something like http://blog.laranjee.com/how-to-convert-winforms-bitmap-to-wpf-imagesource/ – Joel Lucsy Jun 26 '13 at 16:57
  • Yes you have to convert it to the right type. It was a great link Joel – Tan Jun 26 '13 at 19:26