Powered by MSDN

US - English
NEW! Silverlight 5 is available Learn More

Listbox with Canvas as ItemsPanelTemplate: not working RSS

2 replies

Last post Sep 08, 2008 10:32 AM by harmen

(0)
  • harmen

    harmen

    Member

    32 Points

    12 Posts

    Listbox with Canvas as ItemsPanelTemplate: not working

    Sep 08, 2008 08:37 AM | LINK

    Hi,

    I have the following XAML (borrowed from  http://www.planet-xaml.net/page.aspx?article=46, works in WPF):

     

    <UserControl x:Class="TestListBox.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">

    <ListBox x:Name="theListBox" Width="240" Height="300" Background="Red">


    <ListBox.ItemsPanel>
    <ItemsPanelTemplate>
    <Canvas />
    </ItemsPanelTemplate>
    </ListBox.ItemsPanel>

    <ListBox.ItemContainerStyle>
    <Style>
    <Setter Property="Canvas.Left" Value="{Binding Pos.X}" />
    <Setter Property="Canvas.Top" Value="{Binding Pos.Y}" />
    </Style>
    </ListBox.ItemContainerStyle>

    </ListBox>

    </Grid>
    </UserControl>

     With the following datasource set in code:


     

    void Page_Loaded(object sender, RoutedEventArgs e)
    {
    theListBox.ItemsSource = new[]
    {
    new { Title = "Hello", Pos = new Point(200,30) },
    new { Title = "World", Pos = new Point(100,60) }
    };
    }

      

    But it is just not working. When I leave out the ItemContainerStyle, the items are drawn at position 0,0. But with the ItemContainerStyle I get an exception:

    Additional information: AG_E_RUNTIME_MANAGED_UNKNOWN_ERROR [Line: 18 Position: 77]
    An exception of type 'System.Windows.Markup.XamlParseException' occurred in System.Windows.dll but was not handled in user code
    Additional information: AG_E_RUNTIME_MANAGED_UNKNOWN_ERROR [Line: 18 Position: 77]
    Step into: Stepping over non-user code 'MS.Internal.JoltHelper.FireEvent'

    How can I make a Canvas work inside an ListBox.ItemsPanel ? Or a Grid for that matter?

    T.i.a,

    Harmen

    ListBox ItemsPanel Canvas

  • lee_sl

    lee_sl

    Contributor

    4222 Points

    864 Posts

    Re: Listbox with Canvas as ItemsPanelTemplate: not working

    Sep 08, 2008 09:44 AM | LINK

    You will find a link on how this could be done in the comments section here

    http://leeontech.wordpress.com/2008/06/30/itemspaneltemplate-differences-in-sl-and-wpf/

    ----------------------------------------------
    Available for consulting in Dallas, TX
    http://leeontech.wordpress.com/
  • harmen

    harmen

    Member

    32 Points

    12 Posts

    Re: Listbox with Canvas as ItemsPanelTemplate: not working

    Sep 08, 2008 10:32 AM | LINK

    Thanks! The planets ListBox on http://blogs.msdn.com/delay/archive/2008/03/12/lb-sv-why-three-wacky-uses-for-silverlight-2-s-listbox-and-scrollviewer.aspx helped me.Overriding PrepareContainerForItemOverride and binding in code did the trick.

     I ran into a strange thing with my datasource though. I had to explicitly define a class for it or else I would get the following exception in SetBinding on line 45:

     A first chance exception of type 'System.MethodAccessException' occurred in mscorlib.dll
    An exception of type 'System.MethodAccessException' occurred in mscorlib.dll but was not handled in user code
    Additional information: <>f__AnonymousType0`2.get_Pos()

    Working XAML:

     

    <UserControl x:Class="TestListBox.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:l="clr-namespace:TestListBox;assembly=TestListBox"
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">

    <l:MyListBox x:Name="theListBox" Width="240" Height="300" Background="Red">


    <l:MyListBox.ItemsPanel>
    <ItemsPanelTemplate>
    <Canvas />
    </ItemsPanelTemplate>
    </l:MyListBox.ItemsPanel>

    <!--<ListBox.ItemContainerStyle>
    <Style>
    <Setter Property="Canvas.Left" Value="{Binding Pos.X}" />
    <Setter Property="Canvas.Top" Value="{Binding Pos.Y}" />
    </Style>
    </ListBox.ItemContainerStyle>-->


    </l:MyListBox>

    </Grid>
    </UserControl>

      Code behind:

     

    namespace TestListBox
    {
    public partial class Page : UserControl
    {
    public Page()
    {
    InitializeComponent();
    Loaded += new RoutedEventHandler(Page_Loaded);
    }

    void Page_Loaded(object sender, RoutedEventArgs e)
    {
    //theListBox.ItemsSource = new[]
    //{
    // new { Title = "Hello", Pos = new Point(200,30) },
    // new { Title = "World", Pos = new Point(100,60) }
    //};

    theListBox.ItemsSource = new[]
    {
    new MyItem("Hello", new Point(200,30)),
    new MyItem("World", new Point(100,60))
    };
    }
    }

    public class MyItem
    {
    public string Title { get; set; }
    public Point Pos { get; set; }

    public MyItem(string title, Point pos)
    {
    Title = title;
    Pos = pos;
    }
    }

    public class MyListBox : ListBox
    {
    protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
    {
    base.PrepareContainerForItemOverride(element, item);

    ListBoxItem listBoxItem = (ListBoxItem)element;
    listBoxItem.SetBinding(Canvas.TopProperty, new Binding("Pos.Y"));
    listBoxItem.SetBinding(Canvas.LeftProperty, new Binding("Pos.X"));
    }
    }
    }
      

    PrepareContainerForItemOverride