开发者

Get Selected Item from Context Menu

I am creating a set of images dynamically and putting them into a Stack Panel like this :-

            Image image = new Image();
            image.Name = "image_" + iCounter;
            image.Height = 100;
            image.Width = 100;
            image.Source = bitmap;
            image.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
            image.Stretch = Stretch.Fill;
            image.VerticalAlignment = VerticalAlignment.Top;
            //image.MouseDown += new MouseButtonEventHandler(image_MouseDown);
            image.ToolTip = "Right-Click for Options";
            image.ContextMenu = GetContextMenu();

            Separator separator = new Separator();
            separator.Name = "separator_" + iCounter;

            AddImagesStackPanel.Children.Add(image);
            AddImagesStackPanel.Children.Add(separator);

            iCounter++;

Then in the Context Menu I have this code :-

    private System.Windows.Controls.ContextMenu GetContextMenu()
    {
        System.Windows.Controls.MenuItem mi1;
        System.Windows.Controls.MenuItem mi2;
    
        System.Windows.Controls.ContextMenu _contextMenu = new System.Windows.Controls.ContextMenu();
    
        mi1 = new System.Windows.Controls.MenuItem();
        mi1.Header = "Show Normal Size";
        mi1.Click += new RoutedEventHandler(ContextMenuItem1_Click);

        mi2 = new System.Windows.Controls.MenuItem();
        mi2.Header = "Remove image";
        mi2.Click += new RoutedEventHandler(ContextMenuItem2_Click);

        _contextMenu.Items.Add(mi1);
        _contextMenu.Items.Add(mi2);
        return _contextMenu;
    }

Now I wish to get the selected item when the user right clicks on an image and I have this code :-

    private void ContextMenuItem2_Click(object sender, RoutedEventArgs e)
    {
        object obj = e.OriginalSource;

        string imageName = ((System.Windows.Controls.Image)obj).Name;
        string[] split = imageName.Split('_');
        imageUploads.RemoveAt(Convert.ToInt32(split[1]));
        DisplayImagesInStackPanel(imageUploads);
    }

But obj does not contain the name of the image since its开发者_如何转开发 a RoutedEventArgs. Is there any way I can get the selected item in the context menu?


After discussing this in the comments this should work:

// The binding source.
private readonly ObservableCollection<BitmapImage> _imageList = new ObservableCollection<BitmapImage>();
public ObservableCollection<BitmapImage> ImageList
{
    get { return _imageList; }
}

How to display this and set up the ContextMenu:

<ItemsControl ItemsSource="{Binding ImageList}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <Image Source="{Binding}" Width="100" Height="100"
                       HorizontalAlignment="Left" Stretch="Fill"
                       VerticalAlignment="Top" ToolTip="Right-Click for Options">
                    <Image.ContextMenu>
                        <ContextMenu>
                            <MenuItem Header="Show Normal Size" Click="Image_CM_ShowNormalSize_Click"
                                      Tag="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget}"/> <!-- The placement target is the object to which the context menu belongs, i.e. the image -->
                            <MenuItem Header="Remove Image" Click="Image_CM_RemoveImage_Click"
                                      Tag="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.DataContext}"/> <!-- The DataContext of the Image is the BitmapImage, which should be removed from the list -->
                        </ContextMenu>
                    </Image.ContextMenu>
                </Image>
                <Separator/>
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

What the handlers might look like:

private void Image_CM_ShowNormalSize_Click(object sender, RoutedEventArgs e)
{
    Image img = (sender as FrameworkElement).Tag as Image;
    img.Width = (img.Source as BitmapImage).PixelWidth;
    img.Height = (img.Source as BitmapImage).PixelHeight;
}

private void Image_CM_RemoveImage_Click(object sender, RoutedEventArgs e)
{
    BitmapImage img = (sender as FrameworkElement).Tag as BitmapImage;
    // If the image is removed from the bound list the respective visual elements
    // will automatically be removed as well.
    ImageList.Remove(img);
}


But obj does not contain the name of the image since its a RoutedEventArgs.

True, but the obj at that point is a MenuItem, if you drill one level down, you can get the image.

Is there any way I can get the selected item in the context menu?

Normally one would load the model classes (Image in your case) through the binding of ItemSource of the Menu (or MenuItem if they are to be submenus) and if one takes that route they can pull the originating item off of the DataContext such as in my case the item was an MRU class item.

private void SelectMRU(object sender, RoutedEventArgs e)
{
    var mru = (e.OriginalSource as MenuItem).DataContext as MRU;
    var name = mru.Name;
    ...
}

Because you do things by hand you should load the Tag property of the MenuItem with the Image in question

 mi1.Tag = {Image instance in question};

then extract on the event.

 var image = (e.OriginalSource as MenuItem).Tag as Image;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜