Reputation: 520
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
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