Click here to Skip to main content
15,891,657 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Ok so I have an ItemsControl that uses a Canvas as the panel for displaying its items. I want to be able to click on one of these items and have it brought to the front of the canvas or add a menuitem event handler for doing the same thing.

Does anyone know how to do this or workaround? It seems that attached properties such as Canvas.Left/Canvas.Top don't work when the canvas is an itemsHost so I need another solution.

Thanks!
Posted

What I had to do was this: since my ItemsControl's source is bound to non-UI elements, it wraps its items in a ContentPresenter (which is causing me other problems). In order to do anything with what was on the screen, I had to find that particular item's contentpresenter.
ContentPresenter cp = (ContentPresenter)myItemsControl.ItemContainerGenerator.ContainerFromItem((e.Source as SystemBasicView).DataContext);
Canvas.SetZIndex(cp, 999999 + _zIndex);


This is placed withing a mouseDown event, the e.Source being what (on the screen) the mouse clicked on. If it was a particular control (that inflates my viewModel class), then it finds the contentpresenter that the itemscontrol is wrapping my viewModel in and sets its Canvas.SetZIndex accordingly. 999999 was arbitrary, _zIndex increments each time something is clicked so no two UI elements should ever have the same zIndex (unless of course you are working with over 1 million canvas children in my case).
 
Share this answer
 
Comments
AspDotNetDev 6-Aug-10 14:21pm    
Thanks for the update. Good to know.
This answer shows how to bind the left and top of each item. To bring an item to the front, you could probably remove it from the items you are binding to, then re-add it to the end of the collection.
 
Share this answer
 
Comments
industryunleash 5-Aug-10 16:20pm    
Removing it and re-adding it to the collection would be bad for me because a lot of other things are dependent on it and they would get messed up.
AspDotNetDev 5-Aug-10 18:15pm    
In that case, perhaps you can just bind ZIndex like the link I sent you says to bind Canvas.Left and Canvas.Top.
I've tried setting the ItemContainerStyle for my ItemsControl like so:
XML
<ItemsControl.ItemContainerStyle>
            <Style>
                <Setter Property="Canvas.Left" Value="{Binding Position.X}" />
                <Setter Property="Canvas.Top" Value="{Binding Position.Y}" />
                <Setter Property="Canvas.ZIndex" Value="{Binding ZIndex}" />
            </Style>
        </ItemsControl.ItemContainerStyle>


The Position properties bind but the ZIndex one doesn't, or if it does it doesn't change anything on the screen.
 
Share this answer
 
Hmmm, seems you can't bind ZIndex. Not sure why that is. How about something like this (setting it manually):
XML
<Window
    x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Name="MyMainWindow">
    <StackPanel>
        <Canvas Width="300" Height="300" Background="Blue">
            <Ellipse Name="green" Fill="Green" Width="200" Height="100" />
            <Ellipse Name="red" Fill="Red" Width="200" Height="100" Canvas.Left="100" Canvas.Top="50" />
        </Canvas>
        <Button Click="Button_Click">Swap</Button>
    </StackPanel>
</Window>

C#
using System.Windows;
using System.Windows.Controls;
namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            RedIndex = 1;
            GreenIndex = 2;
        }

        private int redIndex;
        private int greenIndex;
        public int RedIndex
        {
            get
            {
                return redIndex;
            }
            set
            {
                if (redIndex != value)
                {
                    redIndex = value;
                    Canvas.SetZIndex(red, redIndex);
                }
            }
        }
        public int GreenIndex
        {
            get
            {
                return greenIndex;
            }
            set
            {
                if (greenIndex != value)
                {
                    greenIndex = value;
                    Canvas.SetZIndex(green, greenIndex);
                }
            }
        }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            int index = RedIndex;
            RedIndex = GreenIndex;
            GreenIndex = index;
        }

    }
}

You'd have to modify that so you can get to the dynamically generated item containers.
 
Share this answer
 

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