Exception passing SelectedItem of a listbox via action

Apr 22, 2011 at 8:15 PM

i'm trying to send a the SelectedItem of my listbox to my viewmodel using an action but its giving me an exception. the xaml looks like

 

<ListBox x:Name="Items" HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch" ItemsSource="{Binding Path=Items}" cal:Message.Attach="[Event SelectionChanged]=[Action SelectedItemChanged($this.SelectedItem)]">

When i run it i get the exception "Target must be a FrameworkElement or a CollectionViewSource." in the Parser.BindParamter method on this line

#if SILVERLIGHT
            var expression = (BindingExpression)BindingOperations.SetBinding(parameter, Parameter.ValueProperty, binding);
What am i doing wrong?

 

Coordinator
Apr 22, 2011 at 8:55 PM

Have you considered binding the SelectedItem to a property on your ViewModel, then executing code in the setter?

Apr 23, 2011 at 9:28 AM

I tried that but the list is binding to a collection of a collection of my datacontext of the page and i can't figure out the binding. Before using caliburn i used mvvm light and it just had a static viewmodel locater that i could use to bind it but i'm not sure how to do this in caliburn. the structure looks something like this.

    public class Library
    {
        public Library()
        {
            Categories = new ObservableCollection<Category>();
            Categories.Add(new Category() { Title = "Science" });
            Categories.Add(new Category() { Title = "Fiction" });
        }
        public ObservableCollection<Category> Categories { get; set; }

    }

    public class Category
    {
        public Category()
        {
            Books = new ObservableCollection<Book>();
            Books.Add(new Book() { Name = "Some Book", Description = "Once apon a time.." });
        }
        public string Title { get; set; }
        public ObservableCollection<Book> Books { get; set; }
    }
    public class Book
    {
        public string Name { get; set; }
        public string Description { get; set; }
    }
}

So i have a panorama control that is bound to a libray class, the panorama tabs are bound to the Categories property of the library and each panorama tab is bound to the books property of the category class like this

 <controls:Panorama x:Name="LibraryPanorama" Title="Library" ItemsSource="{Binding Path=Library.Categories}" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" >
                <controls:Panorama.HeaderTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{Binding Path=Title}" FontSize="48" />
                        </StackPanel>
                    </DataTemplate>
                </controls:Panorama.HeaderTemplate>
                <controls:Panorama.ItemTemplate>
                    <DataTemplate>
                        <controls:PanoramaItem>
                            <ListBox x:Name="Books" HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch" ItemsSource="{Binding Path=Books}">
                                <ListBox.ItemTemplate>
                                    <DataTemplate x:Name="ItemTemplate">
                                        <Grid HorizontalAlignment="Stretch">
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="330"/>
                                                <ColumnDefinition Width="90"/>
                                            </Grid.ColumnDefinitions>
                                            <StackPanel Grid.Column="0">
                                                <TextBlock x:Name="BookName" Text="{Binding Name}" Margin="5" TextWrapping="Wrap" />
                                                <TextBlock x:Name="BookDescription" Text="{Binding Description}" Margin="10,5,5,5" TextWrapping="Wrap" Foreground="#FF7E7E7E"/>
                                            </StackPanel>
                                        </Grid>
                                    </DataTemplate>
                                </ListBox.ItemTemplate>
                            </ListBox>
                        </controls:PanoramaItem>
                    </DataTemplate>
                </controls:Panorama.ItemTemplate>
            </controls:Panorama>

So in my ViewModel i need to track the selected book and the selected category. i can get the category via the panorama selected item changed event but not sure how to get the correct syntax to bind the selected book without having viewmodel instantiated. I think there is probably a better way to design this in caliburn but i'm not really sure how.