views:

324

answers:

1

LowDown: I am trying to create a Document Viewer in WPF. It will allow the user to preview selected documents and if they want, compare the documents in WPF. So they can view them side by side.

The layout is this: Left side is a full list box. On the right side is a Collection or an Items control. Inside the items control will be a collection of the "selected documents" in the list box. So A user can select multiple items in the list box and for each new item they select, they can add the item to the collection on the right. I want the collection to look like a image gallery that shows up in Google/Bing Image searches. Make sense?

The problem I am having is I can't get the WPFPreviewer to bind correctly to the selected item in the list box under the itemscontrol.

Side Note: The WPFPreviewer is something Micorosft puts out that allows us to preview documents. Other previewers can be built for all types of documents, but im going basic here until I get this working right.

I have been successful in binding to the list box WITHOUT the items control here:

<Window.Resources>
    <DataTemplate x:Key="listBoxTemplate">
        <StackPanel Margin="3" >
            <DockPanel >
                <Image Source="{Binding IconURL}" Height="30"></Image>
                <TextBlock Text="  " />
                <TextBlock x:Name="Title" Text="{Binding Title}" 
                    FontWeight="Bold" />
                <TextBlock x:Name="URL" Visibility="Collapsed" 
                    Text="{Binding Url}"/>
            </DockPanel>
        </StackPanel>
    </DataTemplate>
</Window.Resources>
<Grid Background="Cyan">
    <ListBox HorizontalAlignment="Left" 
        ItemTemplate="{StaticResource listBoxTemplate}" Width="200" 
        AllowDrop="True" x:Name="lbDocuments" 
        ItemsSource="{Binding Path=DocumentElements,ElementName=winDocument}"       
        DragEnter="documentListBox_DragEnter"  />
    <l:WPFPreviewHandler
        Content="{Binding ElementName=lbDocuments, Path=SelectedItem.Url}"/>
</Grid>

Though, once I add in the ItemsControl, I can't get it to work anymore:

<Window.Resources>
    <DataTemplate x:Key="listBoxTemplate">
        <StackPanel Margin="3" >
            <DockPanel >
                <Image Source="{Binding IconURL}" Height="30"></Image>
                <TextBlock Text="  " />
                <TextBlock x:Name="Title" Text="{Binding Title}" FontWeight="Bold" />
                <TextBlock x:Name="URL" Visibility="Collapsed" Text="{Binding Url}"/>
            </DockPanel>
        </StackPanel>
    </DataTemplate>
</Window.Resources>
<Grid>
    <ListBox HorizontalAlignment="Left" 
        ItemTemplate="{StaticResource listBoxTemplate}" Width="200" 
        AllowDrop="True" x:Name="lbDocuments" 
        ItemsSource="{Binding Path=DocumentElements,ElementName=winDocument}"
        DragEnter="documentListBox_DragEnter"  />
    <ItemsControl x:Name="DocumentViewer"  
        ItemsSource="{Binding ElementName=lbDocuments, Path=SelectedItem.Url}" >
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid Background="Cyan">
                    <l:WPFPreviewHandler Content="{Binding Url}"/>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

Here is the Class of which is loaded into the ListBox

    public class Document
{
    public string Title { get; set; } 
    public string Url { get; set; } //this is what I want
    public string IconURL { get; set; } //used so I can display the icon of the file
}

Can someone please help me out with trying to bind to the ItemsControl if I select one or even multiple items in the listbox.

+1  A: 

It looks like the error is in your ItemsSource binding. Currently, you are trying to set the ItemsControl to display the Url of the SelectedItem. Instead, you should just bind to the SelectedItems (the s on the property name is really important!) property:

...
<ItemsControl x:Name="DocumentViewer"  
    ItemsSource="{Binding ElementName=lbDocuments, Path=SelectedItems}" >
...

Since you already have a DataTemplate that is using the Url to create the PreviewHandler, this should do what you need.

Edit You need to bind to SelectedItems, and not SelectedItem because SelectedItem is only one object (not a valid ItemsSource), whereas SelectedItems is an IEnumerable of all the items selected.

Abe Heidebrecht
Via your idea, this is the error it gives me (Looks like its trying to convert the document to a usable type):ObjectSourceConverter' converter failed to convert value 'Views.Document' (type 'Document'); fallback value will be used, if available. BindingExpression:Path=SelectedItem; DataItem='ListBox' (Name='lbDocuments'); target element is 'ItemsControl' (Name='DocumentViewer'); target property is 'ItemsSource'
Scott
You need to use SelectedItems (notice the s at the end). This is because one item isn't an IEnumerable, where the SelectedItems collection is... I'll update the answer to call out the SelectedItems more clearly.
Abe Heidebrecht
thanks, that did it!!
Scott