Steel Nation
Steel Nation

Reputation: 520

Using an ItemPresenter within a content presenter possible in WPF?

I'm trying to get a ListBox to change its back ground from a Grid to a user selected Image at the click of a Button. Besides the background, the list box contains a collection of UI elements that are bound to an ObservableCollection via ItemSource, and then presented via item presenter.

Originally I had the background XML within the ListBox's template, and this worked fine up until I needed to put a content presenter in there to give the user the option to selected different back grounds.

The background updates fine, it's just that none of the ListBox items show up. Any idea why this is happening? Here is the code:

<ListBox SelectedItem="{Binding SelectedObject}" 
                 PreviewMouseMove="ListBox_PreviewMouseMove"
                 PreviewMouseDown="ListBox_PreviewMouseDown">
                <ListBox.Template>
                    <ControlTemplate>
                        <!--<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" Content="{Binding DataContext.BackgroundType, Source={x:Reference view}}">-->
                        <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
                            <Border>
                                <ContentPresenter Content="{Binding DataContext.BackgroundType, Source={x:Reference view}}">
                                    <ContentPresenter.Resources>
                                        <DataTemplate DataType="{x:Type local:GridBackType}">
                                            <Border>
                                                <Border.Background>
                                                <VisualBrush TileMode="Tile" Viewport="{Binding DataContext.GridSize, Source={x:Reference view}}" 
                                                             ViewportUnits="Absolute" Viewbox="0,0,50,50" ViewboxUnits="Absolute">
                                                    <VisualBrush.Visual>
                                                        <Rectangle Stroke="Blue" StrokeThickness="1" Height="50" Width="50"
                                                                   StrokeDashArray="5 3">
                                                        </Rectangle>
                                                    </VisualBrush.Visual>
                                                </VisualBrush>
                                            </Border.Background>
                                                <ItemsPresenter/>
                                            </Border>
                                        </DataTemplate>
                                    </ContentPresenter.Resources>
                                </ContentPresenter>
                            </Border>
                        </ScrollViewer>
                    </ControlTemplate>
                </ListBox.Template>
                <ListBox.ItemsSource>
                    <StaticResource ResourceKey="Col"/>
                </ListBox.ItemsSource>
                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Canvas IsItemsHost="True" Background="#01FFFFFF" 
                            Height="{Binding AreaHeight}" Width="{Binding AreaWidth}"
                            VerticalAlignment="Top" HorizontalAlignment="Left"/>
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>
                <ListBox.ItemContainerStyle>
                    <Style TargetType="ListBoxItem">
                        <Setter Property="Canvas.Left" Value="{Binding X}"/>
                        <Setter Property="Canvas.Top" Value="{Binding Y}"/>
                        <Setter Property="FocusVisualStyle" Value="{StaticResource EmptyFocusVisualStyle}"/>
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="ListBoxItem">
                                    <ContentPresenter x:Name="Content"/>
                                    <ControlTemplate.Triggers>
                                        <Trigger Property="IsSelected" Value="True">
                                            <Setter TargetName="Content" Property="Effect">
                                                <Setter.Value>
                                                    <DropShadowEffect Color="Gray" ShadowDepth="4" BlurRadius="10"/>
                                                </Setter.Value>
                                            </Setter>
                                        </Trigger>
                                        <DataTrigger Binding="{Binding IsNew}" Value="True">
                                            <Setter Property="Opacity" Value=".5"/>
                                        </DataTrigger>
                                    </ControlTemplate.Triggers>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </ListBox.ItemContainerStyle>
            </ListBox>

And the code for the BackgroundType class:

namespace NodesEditor
{
public abstract class BackgroundTypes : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

public class ImageBackType : BackgroundTypes { }
public class GridBackType : BackgroundTypes { }
}

Upvotes: 1

Views: 1149

Answers (1)

Fede
Fede

Reputation: 44028

You could use a Grid to place the ItemsPresenter "above" (in Z-Index) of the Background panel, thus leaving the ItemsPresenter always in place while being able to modify the Background contents:

<Grid>
    <ContentPresenter Content="{Binding DataContext.BackgroundType, Source={x:Reference view}}">
        <ContentPresenter.Resources>
            <!-- etc -->
        </ContentPresenter.Resources>
    </ContentPresenter>
    <ItemsPresenter/>
</Grid>

Upvotes: 2

Related Questions