How to use behaviors in Universal Windows Platform? - c#

I'm trying to add behaviors for my card game, but don't understand how to use them in proper way - where to put the behavior etc.
I have a listbox of cards (cards are loaded from images) and want to move card up when its clicked and move down when its clicked again.
Can anyone suggest me guide on how to use behaviors in UWP apps or give me an example on my code ( which is not working:( ).
<Page.Resources>
<Storyboard x:Key="storyboard1" >
</Storyboard>
</Page.Resources>
<ListView x:Name="list" Grid.Row="0" Grid.Column="0" Padding="50,0" ScrollViewer.VerticalScrollBarVisibility="Disabled" VerticalAlignment="Center" HorizontalContentAlignment="Stretch" ItemClick="ListView_ItemClick" >
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Margin" Value="0,0,-70,0"></Setter>
<Setter Property="MaxHeight" Value="100"></Setter>
<Setter Property="MaxWidth" Value="68"></Setter>
<Setter Property="Padding" Value="0,0,0,0"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<ListViewItemPresenter>
<interactivity:Interaction.Behaviors>
<interactions:EventTriggerBehavior EventName="GotFocus">
<media:ControlStoryboardAction Storyboard="{StaticResource storyboard1}">
</media:ControlStoryboardAction>
</interactions:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</ListViewItemPresenter>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
<ListViewItem>
</ListViewItem>
<Image x:Name="One" MaxWidth="68" Height="100" >
<interactivity:Interaction.Behaviors>
<interactions:EventTriggerBehavior>
<media:ControlStoryboardAction Storyboard="{StaticResource storyboard1}">
</media:ControlStoryboardAction>
</interactions:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</Image>
<Image x:Name="Two" MaxWidth="68" Height="100" />
<Image x:Name="Three" MaxWidth="68" Height="100" />
</ListView>

Related

Wpf : How to make a letter pop out of the border

how do make a letter pop out of the border?
I want to express it like this picture
I wrote a letter in the text on Border,
The letters are covered like in the picture.
Can you make this stick out like the picture below?
How can solve this?
this is my xaml code
<Window x:Class="TestProject.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestProject"
Width="800"
Height="600"
Title="ItemsControl 엘리먼트 : Template/ItemsPanel/ItemTemplate/ItemContainerStyle 속성 사용하기"
FontFamily="나눔고딕코딩"
FontSize="16">
<Window.Resources>
<local:TaskCollection x:Key="TaskCollectionKey" />
</Window.Resources>
<Grid>
<ItemsControl
HorizontalAlignment="Center"
VerticalAlignment="Center"
ItemsSource="{Binding Source={StaticResource TaskCollectionKey}}">
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<Border
BorderBrush="Black"
BorderThickness="3"
CornerRadius="15">
<ItemsPresenter />
</Border>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<DataTemplate.Resources>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
</DataTemplate.Resources>
<Grid>
<Ellipse
Stroke="Black"
StrokeThickness="3"
Fill="Gold" />
<StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center">
<TextBlock
Margin="5"
Text="{Binding Path=Priority}" />
<TextBlock
Margin="5"
Text="{Binding Path=TaskName}" />
</StackPanel>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Control.Margin" Value="10" />
<Setter Property="Control.Width" Value="100" />
<Setter Property="Control.Height" Value="100" />
<Style.Triggers>
<Trigger
Property="Control.IsMouseOver" Value="True">
<Setter Property="Control.ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=Content.Description}" />
</Trigger>
</Style.Triggers>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</Grid>
</Window>
If you put the textblock in a canvas, that will not clip.
<StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center">
<TextBlock
Margin="5"
Text="{Binding Path=Priority}" />
<Canvas>
<TextBlock
Text="{Binding Path=TaskName}" />
</Canvas>
</StackPanel>

How do I better stylize a ListBox of images in WPF?

I've binded a List from my code-behind to a ListBox but I'm having difficulty stylizing the look to get what I want. I'd like to show up to 8 images at once, but no more than that without scrolling down. When the window resizes, I would like the image sizes to scale with it but still have no more than 8 showing. Here's my current XAML:
<ListBox ItemsSource="{Binding PictureImagesList}">
<ListBox.Template>
<ControlTemplate TargetType="ListBox">
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
<ItemsPresenter/>
</ScrollViewer>
</ControlTemplate>
</ListBox.Template>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="4" HorizontalAlignment="Center" VerticalAlignment="Top" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}"/>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}" >
<Grid Background="{TemplateBinding Background}">
<Border HorizontalAlignment="Center" VerticalAlignment="Center"
BorderBrush="{TemplateBinding BorderBrush}">
<ContentPresenter />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="BorderBrush" Value="Yellow" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Here's a pic of what this XAML produces. As you can see the images are much too large and we only see the top half of the second row. If I mess around with ListBoxItem margin I can get them smaller but this isn't really ideal as it only works if the screen resolution stays the same.
Set your image dimensions to be the same and use a WrapPanel instead:
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Border Margin="5" >
<Image Source="{Binding}" Stretch="Uniform" Width="400" Height="400"/>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
Alternatively, if you want a fixed number of columns then don't specify image dimensions at all and instead use a UniformGrid:
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Border Margin="5" >
<Image Source="{Binding}" Stretch="Uniform" />
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<UniformGrid Columns="3" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
UPDATE: I'm at a bit of a loss now to understand exactly what it is you're trying to do, the images you're posting don't match your description. If you want the panels to be square, and the images to scale up to them uniformly with a thin border around them, then there are a few things you'll have to do:
1) change your ListBoxItem ControlTemplate to be a Border with a Transparent background and the ContentPresenter inside it. This will ensure that your yellow border doesn't fill the whole box, and that the rest of the box doesn't highlight when selected, but that you can still click anywhere on it to select it.
2) change your ItemTemplate to be a grid (so that it fills all available space) with a border centered in the middle of it with padding (so that you'll be able to see the yellow border when selected), then put your Image content inside that but wrap.
This should do the job:
<Style TargetType="{x:Type ListBox}" x:Key="PictureListBoxStyle">
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Grid Margin="5">
<Border Padding="5" HorizontalAlignment="Center" VerticalAlignment="Center">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="Transparent" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}}" Value="True">
<Setter Property="Background" Value="Yellow" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<Image Source="{Binding}" Stretch="Uniform" />
</Border>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<UniformGrid Columns="3" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
</Style>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}" >
<Border Background="Transparent">
<ContentPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
If that still isn't it then you'll need to define your requirements more clearly.
You could use a UniformGrid as ItemsPanel with appropriate HorizontalAlignment and VerticalAlignment. Also remove the redundant Border element from the DataTemplate.
<ListBox ItemsSource="{Binding PictureImagesList}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="4" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Image Width="200" Height="200" Margin="5" Source="{Binding}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Update: In order to have the yellow selection border directly around the image, use a ListBoxItem Style like shown below. To have the images scaled to (a fraction of) the full ListBox width, add an appropriate ControlTemplate.
<ListBox ItemsSource="{Binding PictureImagesList}">
<ListBox.Template>
<ControlTemplate TargetType="ListBox">
<ScrollViewer HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto">
<ItemsPresenter/>
</ScrollViewer>
</ControlTemplate>
</ListBox.Template>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="4" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}"/>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Background" Value="LightGray" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}" >
<Grid Background="{TemplateBinding Background}">
<Border HorizontalAlignment="Center" VerticalAlignment="Center"
BorderThickness="5"
BorderBrush="{TemplateBinding BorderBrush}">
<ContentPresenter />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="BorderBrush" Value="Yellow" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>

How to overlay items in StackPanel or ListView?

I am making a card game and I want to display cards in player's hand half-covered be each other. How can I do that using ListView or StackPanel? Here is an example how I would like to display player hand.
<Grid Background="Green" >
<Image x:Name="One" Width="100" Height="100" Margin="10,10,250,210"/>
<Image x:Name="Two" Width="100" Height="100" Margin="10,10,210,210"/>
</Grid>
UPDATE
I set margins for ListView's ItemContainerStyle and it worked, but I have another problem. Width of ListView items doesn't fit the image and there is some spacing. How do I remove that. See image below the XAML code.
<ListView Grid.Row="0" Grid.Column="0">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Margin" Value="0, 0, -80, 0"></Setter>
<Setter Property="Height" Value="100"></Setter>
<Setter Property="Width" Value="100"></Setter>
</Style>
</ListView.ItemContainerStyle>
<Image x:Name="One" MaxWidth="100" Height="100" />
<Image x:Name="Two" MaxWidth="100" Height="100" />
</ListView>
I would use Canvas in the list, and draw your card to the canvas, because things drawn in a canvas are not clipped, and instead managed through the canvas ZIndex etc.
Size the canvas based on your desired spacing, and oversize the contents. I'd also recommend binding to Items-source when using listboxes and using templates.
BTW I'm defining my cards using solidColorBrushes so I can just draw rectangles, replace this with your image source. I've defined my source in the resources, but in reality it would be bound to an ObservableCollection (Say, PlayersCurrentHand or something):
<UserControl.Resources>
<x:Array Type="{x:Type SolidColorBrush}" x:Key="Cards">
<SolidColorBrush Color="Blue"/>
<SolidColorBrush Color="Red"/>
<SolidColorBrush Color="White"/>
<SolidColorBrush Color="White"/>
<SolidColorBrush Color="White"/>
<SolidColorBrush Color="White"/>
</x:Array>
</UserControl.Resources>
Now, I presume you are using ListBox because you want to support selection? If so, the way WPF highlights list box items will mess up with this overlap, so we will need to replace it. If you don't want selection, just use an itemsControl and you can skip all the selection stuff.
Here's our basic listbox:
<ListView ItemsSource="{StaticResource Cards}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="112,98,-325,-25" Width="513" Height="227">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" IsItemsHost="True" VerticalAlignment="Top"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="1">
<Rectangle Fill="{Binding}" Width="60" Height="100"/>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Which gives us this:
Now, we want to have all the list items to be drawn in a canvas, so let's define our ItemContainerStyle:
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<StackPanel>
<Canvas Width="15" Height="100">
<ContentPresenter />
</Canvas>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
See how we've set the canvas Width to 15? That defines the spacing of our cards. All the canvases are stacked at intervals of 15. However, the Rectangles we are drawing in our DateTemplate is Width 60, so these spill off to the right.
We've overridden the messy standard selection and highlighting styles. But no we don't know what's highlighted and selected, so let's add some functionality back in. We can also add things like shadows etc:
<ControlTemplate TargetType="{x:Type ListViewItem}">
<StackPanel>
<Canvas Width="15" Height="100">
<Rectangle x:Name="Highlight" Width="60" Height="5" Canvas.Top="105"/>
<Rectangle Fill="#50000000" Width="60" Height="100" Margin="5,0,-5,0"/>
<ContentPresenter />
</Canvas>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Highlight" Property="Fill" Value="Yellow"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Panel.ZIndex" Value="99"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
So now we have this:
Note, the gif didn't render the selection exactly right. The width issue is going to be tricky to fix without some code behind I think. One option is to make an IValueConverter that calculates width given the List of cards, and binding it to the Listview's Width property.
Edit
Found a way to get around the size issue! Padding! Of course. However, I found the scroll viewer clips even the canvas it contains (which makes sense if you think about it) but leaves all our effort hidden:
So you have to overwrite the scroll viewer functionality by setting the ControlTemplate manually:
<ListBox.Template>
<ControlTemplate>
<Border Padding="5,25,55,15" BorderBrush="Gray" BorderThickness="1">
<ItemsPresenter />
</Border>
</ControlTemplate>
</ListBox.Template>
So now the padding accounts for the last card sticking out an extra 50.
Total code, with some more visual tweaks:
<ListView ItemsSource="{StaticResource Cards}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="20" BorderBrush="Black">
<ListBox.Template>
<ControlTemplate>
<Border Padding="5,25,55,15" BorderBrush="Gray" BorderThickness="1">
<ItemsPresenter />
</Border>
</ControlTemplate>
</ListBox.Template>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" IsItemsHost="True" ClipToBounds="False" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<StackPanel>
<Canvas Width="15" Height="100">
<Rectangle x:Name="Highlight" Width="60" Height="5" Canvas.Top="105"/>
<ContentPresenter x:Name="CardPresenter"/>
</Canvas>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Panel.ZIndex" Value="99"/>
<Setter TargetName="CardPresenter" Property="Canvas.Top" Value="-5"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Highlight" Property="Fill" Value="Yellow"/>
<Setter TargetName="CardPresenter" Property="Canvas.Top" Value="-20"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Border Background="#60000000" BorderThickness="0" CornerRadius="5" Height="100" Margin="5,0,-5,0"/>
<Border BorderBrush="Black" BorderThickness="1" CornerRadius="5" Background="{Binding}" Width="60" Height="100"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
It's pretty flexible, it was easy to add the "sticking out" functionality. Animations would be the next big step.
Edit 2
I'm just playing now. I'm not sure I like the "jump to the front" functionality, would be better if they just peeked out. Also, fanning them out (using a multi-binding):
Using the following template:
<ControlTemplate TargetType="{x:Type ListViewItem}">
<StackPanel>
<Canvas Width="15" Height="100">
<Rectangle x:Name="Highlight" Width="60" Height="5" Canvas.Top="105"/>
<ContentPresenter x:Name="CardPresenter">
<ContentPresenter.RenderTransform>
<TransformGroup>
<TranslateTransform x:Name="TranslateTransformHighlight"/>
<RotateTransform x:Name="RotateTransformHighlight" CenterY="100"/>
<TranslateTransform x:Name="TranslateTransformSelect"/>
</TransformGroup>
</ContentPresenter.RenderTransform>
</ContentPresenter>
</Canvas>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True" >
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="TranslateTransformHighlight" Duration="0:0:0.200" To="-5" Storyboard.TargetProperty="Y" />
<DoubleAnimation Storyboard.TargetName="RotateTransformHighlight" Duration="0:0:0.200" To="-5" Storyboard.TargetProperty="Angle" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="TranslateTransformHighlight" Duration="0:0:0.200" To="0" Storyboard.TargetProperty="Y" />
<DoubleAnimation Storyboard.TargetName="RotateTransformHighlight" Duration="0:0:0.200" To="0" Storyboard.TargetProperty="Angle" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Highlight" Property="Fill" Value="Yellow"/>
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="TranslateTransformSelect" Duration="0:0:0.200" To="-15" Storyboard.TargetProperty="Y" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="TranslateTransformSelect" Duration="0:0:0.200" To="0" Storyboard.TargetProperty="Y" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>

How to keep MVVM pattern with WPF Path object click?

On a WPF app, I got a Canvas object containing several Path object. I need to do things on click on those Path, things that would be in VM. There is no Command on Path, like Button for example. What is the best way to do that?
My solution so far is :
To create an MouseDown handler on the view code behind to catch my Path click
Send a message from here
Register to this message type on targeted VM in order to execute my business code.
It seems a bit overkill to me, what's your opinion? Do you see a more straitforward method?
Thanks a lot !
You can use Button with Path as Template:
<Button Command="{Binding MyCommand}">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Path ... />
</ControlTemplate>
</Button.Template>
</Button>
Just to add complementary infos about my last comment... The right way to position ItemTemplate is to style the ContentPresenter, within ItemsControl.ItemContainerStyle. Below you will find my finally working code :
<UserControl.Resources>
<Style x:Key="PathStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Path Data="{Binding Data}"
StrokeStartLineCap="Round"
Stretch="Fill"
StrokeEndLineCap="Round"
Stroke="{DynamicResource selectedZoneBorderColor}"
StrokeLineJoin="Round"
Width="{Binding Path=Width}"
Height="{Binding Path=Height}"
Fill="{DynamicResource selectedZoneColor}"
Panel.ZIndex="1"
StrokeThickness="3" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<ItemsControl Name="zonesContainer" ItemsSource="{Binding Zones}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Grid.Column="1" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button
Style="{StaticResource ResourceKey=PathStyle}"
Command="{Binding ElementName=zonesContainer,
Path=DataContext.ActivateZone}"
CommandParameter="{Binding Id}"
/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Path=Left}" />
<Setter Property="Canvas.Top" Value="{Binding Path=Top}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
All this with corresponding VM exposing a ObservableCollection, and a Zone class exposing all inside props (Width, Height, Top, Left...).
You can detailled answer here

IsMouseOver event defined in a style is not triggered

This is defined in App.xaml inside <Application.Resources> :
<Style x:Key="borderStyle" TargetType="Border">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
And I am using it here inside Window1.xaml :
<ListBox Name="listView1" ItemsSource="{Binding}" Background="Black" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Width="{Binding (FrameworkElement.ActualWidth), RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}" Orientation="Horizontal" ItemWidth="150" ItemHeight="150" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Border BorderThickness="5" BorderBrush="DarkGray" Style="{StaticResource borderStyle}">
<Image Width="120" Height="120" Stretch="Fill" Source="{Binding Image}" />
</Border>
<TextBlock FontFamily="Verdana" Foreground="Orange" Text="{Binding Title}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
But it doesn't work, when I mouse over it, the border doesn't change the color.
What am I doing wrong ?
Thanks.
You are overriding the trigger if you define the property directly within the border.
Remove BorderBrush="DarkGray"from this line
<Border BorderThickness="5" BorderBrush="DarkGray" Style="{StaticResource borderStyle}">
so it looks like this
<Border BorderThickness="5" Style="{StaticResource borderStyle}">
and add a setter to your style
<Style x:Key="borderStyle" TargetType="Border">
<Setter Property="BorderBrush" Value="DarkGray" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
As a thumb rule: all properties which should be modified by triggers have to be defined as setters within the style.

Categories