2

I've made an app that streams video from a video device and added the ability to take screenshots of the video, when a capture is taken it shows up in the ItemsControl with the rest of the captures taken.

My question is how can i make each item "image" shown in the ItemsControl clickable so i can preview it ?

I store the image details in a list :

List<ImageDetails> images = new List<ImageDetails>();

This is the Xaml code of the ItemsControl :

Edit : I wrapped everything inside a button template inside the datatemplate and i called a mousebuttonclickup event on the button but nothing happens. Did i misplaced the button template ?

 <ItemsControl Name="ImageList" ItemsSource="{Binding ImageList}" >
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Button Width="auto" Height="auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MouseLeftButtonUp="Button_MouseLeftButtonUp">
                        <Button.Template>
                            <ControlTemplate>
                                <Border x:Name="imagecanv" BorderThickness="1" BorderBrush="#FFD0D1D7" Padding="5" Margin="5,5,0,0" MouseLeftButtonUp="imagecanv_MouseLeftButtonUp">
                                    <StackPanel Orientation="Horizontal">
                                        <!--image and dimensions-->
                                        <Grid x:Name="picgrid" Width="88" Height="55">
                                            <Image x:Name="imgcontainer"  Source="{Binding Path}" MouseLeftButtonUp="imgcontainer_MouseLeftButtonUp"/>
                                            <TextBlock Background="#B2000000" Foreground="White" Height="16" TextAlignment="Center" VerticalAlignment="Bottom">
                                                <TextBlock.Text>
                                                    <MultiBinding StringFormat="{}{0}x{1}">
                                                        <Binding Path="Height"/>
                                                        <Binding Path="Width"/>
                                                    </MultiBinding>
                                                </TextBlock.Text>
                                            </TextBlock>
                                        </Grid>
                                        <!--name, type and size-->
                                        <StackPanel Orientation="Vertical" Margin="5,0,0,0" VerticalAlignment="Center">
                                            <TextBlock Name="ImageName" Margin="1" Foreground="#FF787878" Text="{Binding FileName}"/>
                                            <TextBlock Name="ImageType" Margin="1" Foreground="#FF787878">
                                                <TextBlock.Text>
                                                    <MultiBinding StringFormat="Type: {0}">
                                                        <Binding Path="Extension"/>
                                                    </MultiBinding>
                                                </TextBlock.Text>
                                            </TextBlock>
                                            <TextBlock Name="ImageSize" Margin="1" Foreground="#FF787878">
                                                <TextBlock.Text>
                                                    <MultiBinding StringFormat="Size: {0} Bytes">
                                                        <Binding Path="Size"/>
                                                    </MultiBinding>
                                                </TextBlock.Text>
                                            </TextBlock>
                                        </StackPanel>
                                    </StackPanel>
                                </Border>
                                </ControlTemplate>
                                    </Button.Template>
                                        </Button>
                                     </DataTemplate>
            </ItemsControl.ItemTemplate>
            <ItemsControl.ItemsPanel>                   
                <ItemsPanelTemplate >                       
                    <StackPanel x:Name="stackeditems" Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.Template>
                <ControlTemplate>
                    <ScrollViewer Name="Scroller" Padding="{TemplateBinding Padding}" HorizontalScrollBarVisibility="Visible" >
                        <ItemsPresenter />
                    </ScrollViewer>
                </ControlTemplate>
            </ItemsControl.Template>               
        </ItemsControl>

The click event:

private void Button_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        MessageBox.Show("Clickable!");
    }

This is the code behind for viewing the captures :

 private void capture_Click(object sender, RoutedEventArgs e)
    {
        // Create a Bitmap of the same dimension of panelVideoPreview (Width x Height)
        using (Bitmap bitmap = new Bitmap(viewpanel.Width, viewpanel.Height))
        {
            using (Graphics g = Graphics.FromImage(bitmap))
            {
                // Get the paramters to call g.CopyFromScreen and get the image
                System.Drawing.Rectangle rectanglePanelVideoPreview = viewpanel.Bounds;
                System.Drawing.Point sourcePoints = viewpanel.PointToScreen(new System.Drawing.Point(viewpanel.ClientRectangle.X, viewpanel.ClientRectangle.Y));
                g.CopyFromScreen(sourcePoints, System.Drawing.Point.Empty, rectanglePanelVideoPreview.Size);
            }

            string strGrabFileName = String.Format(@"d:\app result\\Snapshot_{0:yyyyMMdd_hhmmss}.jpg", DateTime.Now);

            try
            {
                bitmap.Save(strGrabFileName, System.Drawing.Imaging.ImageFormat.Jpeg);
                imageview(strGrabFileName);
            }
            catch (Exception)
            {


            }                
        } 
    }

 public void imageview (string file)
    {          

            ImageDetails id = new ImageDetails()
            {
                Path = file,
                FileName = System.IO.Path.GetFileName(file),
                Extension = System.IO.Path.GetExtension(file)
            };

            BitmapImage img = new BitmapImage();
            img.BeginInit();
            img.CacheOption = BitmapCacheOption.OnLoad;
            img.UriSource = new Uri(file, UriKind.Absolute);
            img.EndInit();
            id.Width = img.PixelWidth;
            id.Height = img.PixelHeight;

            // I couldn't find file size in BitmapImage
            FileInfo fi = new FileInfo(file);
            id.Size = fi.Length;
            images.Add(id);
            //images.Insert(i, id);
            ImageList.ItemsSource = null;
            ImageList.ItemsSource = images;
    }
Sam Nasser
  • 311
  • 5
  • 13

2 Answers2

4

Have you thought about using commanding instead of click events? Given that you're using WPF and not Silverlight, here's what I've done to achieve click functionality for DataTemplates rendered in an ItemsControl:

<DataTemplate x:Key="YourDataTemplate">
        <TextBlock>
            <TextBlock.InputBindings>
                <MouseBinding 
                    MouseAction="LeftClick" 
                    Command="{Binding YourCommand}"
                    CommandParameter="{Binding YourCommandParameter}"></MouseBinding>
            </TextBlock.InputBindings>
        </TextBlock>
</DataTemplate>

The secondary advantage to this is that you avoid reliance on (relatively untestable) code-behind.

If you'd like to stick with click events, have you considered making the top-level control in the DataTemplate a Button? You can just remove the styling from the button as you see fit, if necessary. Button still has a Click property in DataTemplates, and you can call its DataContext in the click even to get the original ImageDetails object you used for binding.

furkle
  • 5,019
  • 1
  • 15
  • 24
0

You can try various different things for this to implement. Check the answers from this question

Community
  • 1
  • 1
Umair
  • 4,864
  • 3
  • 28
  • 47
  • I managed to get the click event working, my question now is how can i access the image control to get the path of the image i clicked on – Sam Nasser Oct 26 '14 at 13:55
  • If you used the first method, you can get the object from the CommandParameter you passed to the click event. You can use that. – Umair Oct 26 '14 at 14:08
  • i didn't use either of the methods in the link, i added a mouseclickup event on the border around each image, but i also want to open the image i just clicked on. – Sam Nasser Oct 26 '14 at 15:10