Click here to Skip to main content
15,886,788 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
I am trying to display the name of a Photo object in a Label, but I am displaying this Photo in specific control System.Windows.Image, this control has a binding to the CurrentItem of a collection of Photos, so if I have a button to display the next Photo, I want to show in my Label the Name of the Photo(the currentItem of the collection!!!!) or another Property inside the object.

public class Photo
{
Name name;
BitmapFrame _image;

public Photo(string path)
{
Name = path;
Uri source = new Uri(path);
_image = BitmapFrame.Create(_source);
}

public BitmapFrame ImageFrame { get { return _image; } set { _image = value; } }
}

public partial class ImageViewer : Window
{
int currentIndex = 0;
ObservableCollection<Photo> photos;

public ImageViewer()
{
InitializeComponent();

photos = new ObservableCollection<Photo>();

Photo photo1 = new Photo(@"C:/Users/.../DSC00700.jpg");
Photo photo2 = new Photo(@"C:/Users/../DSC00581.jpg");
Photo photo3 = new Photo(@"C:/Users/../3882_6.jpg");

photos.Add(photo1);
photos.Add(photo2);
photos.Add(photo3);

//datacontext of the window
this.DataContext = photos;
}

private void NextPhoto(object sender, RoutedEventArgs e)
{
currentIndex++;
if (currentIndex == photos.Count)
currentIndex = 0;
image.Source = photos[currentIndex].ImageFrame;
}
}

the xaml code:

<Image
Grid.Column="0"
Grid.Row="0"
Name="image"
Stretch="Fill"
DataContext ="{Binding /}"
Source="{Binding ImageFrame}"
>
</Image>

<TextBlock
DataContext="{Binding /}" or something like this: DataContext={"Binding ElementName=image", Path=DataContext<}
Text="{Binding Name}">
</TextBlock>
Posted

1 solution

Instead of setting the Window DataContext to the entire collection, what about setting it to the currently selected item? Then the image Source property can be binded to ImageFrame (like you have already redundantly done - you do it in code too) and the TextBlock Text property can be binded to Name like you have it. You can get rid of the DataContext binding on the TextBlock and the Image since you'd be using the inherited DataContext.

Note you're going to need to provide a property in your Photo class to bind to for the name...a private field isn't going to work.

Here's an example (I did this in Silverlight since you mention Silverlight in your tags...same things apply to WPF. Also note that I changed the URIs for my test code so I could use my images.)
public partial class ImageTestPage : UserControl
{
    int currentIndex = 0;
    ObservableCollection<Photo> photos = new ObservableCollection<Photo>();

    public ImageTestPage()
    {
        InitializeComponent();

        photos.Add(new Photo("Images/Airplane.png"));
        photos.Add(new Photo("Images/Silverlight_Logo.jpg"));

        this.DataContext = photos[currentIndex];
    }

    private void NextPhoto(object sender, RoutedEventArgs e)
    {
        currentIndex++;
        if (currentIndex == photos.Count)
            currentIndex = 0;
        this.DataContext = photos[currentIndex];
    }
}


public class Photo
{
    BitmapImage _image;

    public Photo(string path)
    {
        Name = path;
        Uri source = new Uri(path, UriKind.Relative);
        _image = new BitmapImage(source);
    }

    public string Name { get; set; }
    public BitmapImage ImageFrame { get { return _image; } set { _image = value; } }
}

<Grid x:Name="LayoutRoot" Background="White">
    <Button Name="nextButton" Content="Next" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10" Click="NextPhoto" />
    <Image Grid.Column="0"
           Grid.Row="0"
           Stretch="Fill"
           Source="{Binding ImageFrame}"
           Margin="40" />
    <TextBlock Text="{Binding Name}" Margin="10,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Bottom" />
</Grid>
 
Share this answer
 
v3

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900