How to change ZIndex inside a bound ItemsControl? - c#

I simply created 3 borders in a StackPanel like this:
<StackPanel Orientation="Horizontal" >
<Border Width="100" Height="30" Background="Red" BorderBrush="DarkRed" BorderThickness="4" Margin="0" >
<Border.Style>
<Style TargetType="Border">
<Setter Property="Panel.ZIndex" Value="0"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Panel.ZIndex" Value="1"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
<Border Width="100" Height="30" Background="Blue" BorderBrush="DarkBlue" BorderThickness="4" Margin="-10,0,0,0" >
<Border.Style>
<Style TargetType="Border">
<Setter Property="Panel.ZIndex" Value="0"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Panel.ZIndex" Value="1"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
<Border Width="100" Height="30" Background="Green" BorderBrush="DarkGreen" BorderThickness="4" Margin="-10,0,0,0" >
<Border.Style>
<Style TargetType="Border">
<Setter Property="Panel.ZIndex" Value="0"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Panel.ZIndex" Value="1"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
</StackPanel>
the xaml will layout 3 different colors borders:
When i mouse over the blue one, it'll on the top of others:
But when I move all of these into a ItemsControl, mouse on blue border no longer on the top of others, it just stay it's original ZIndex.
<DataTemplate x:Key="BorderTemplate">
<Border Width="100" Height="30" >
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="Red"/>
<Setter Property="BorderBrush" Value="DarkRed"/>
<Setter Property="BorderThickness" Value="4"/>
<Setter Property="Panel.ZIndex" Value="0"/>
<Setter Property="Margin" Value="0,0,0,0"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Type}" Value="2">
<Setter Property="Background" Value="Blue"/>
<Setter Property="BorderBrush" Value="DarkBlue"/>
<Setter Property="BorderThickness" Value="4"/>
<Setter Property="Panel.ZIndex" Value="0"/>
<Setter Property="Margin" Value="-10,0,0,0"/>
</DataTrigger>
<DataTrigger Binding="{Binding Type}" Value="3">
<Setter Property="Background" Value="Green"/>
<Setter Property="BorderBrush" Value="DarkGreen"/>
<Setter Property="BorderThickness" Value="4"/>
<Setter Property="Panel.ZIndex" Value="0"/>
<Setter Property="Margin" Value="-10,0,0,0"/>
</DataTrigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Panel.ZIndex" Value="1"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
</DataTemplate>
<ItemsControl ItemsSource="{Binding Borders}" ItemTemplate="{StaticResource BorderTemplate}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate >
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
So why Panel.ZIndex worked in StackPanel but not work in ItemsControl->StackPanel?

ZIndex is by no means limited to canvas, so let's not push that idea off on other readers Maximus. However, since you're now loading your stuff as an ItemTemplate, using just a ContentPresenter, so you're basically sandboxing your object in a panel not associated to the overall DOM. Try instead to throw your influence at the ContentPresenter as the object being your container instead of disassociated children nested in it individually. Something like this (after you pull the same triggers off each Border of course).
<ItemsControl.ItemContainerStyle>
<Style TargetType="{x:Type ContentPresenter}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Panel.ZIndex" Value="100" />
</Trigger>
</Style.Triggers>
</Style>
</ItemsControl.ItemContainerStyle>
Hope this helps. Cheers.

Related

Not able to change foreground of label in ListBoxItem [duplicate]

This question already has answers here:
WPF set border background in trigger
(1 answer)
WPF Trigger won't set property if set in Element
(3 answers)
Closed last year.
Below is the sample code of my WPF xaml file. My intention is to change the foreground of the label in the listboxitem to Red colour when the item is selected. However, no changes was seen on the foreground? What mistake had I done?
<UserControl.Resources>
<Style x:Key="WishlistListBoxStyle" TargetType="{x:Type ListBox}">
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="FontSize" Value="18"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="Background" Value="#282C2F"/>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="ListBoxItem">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="WishlistBorder" Style="{DynamicResource WishlistBorderContent}">
<ContentPresenter />
</Border>
<ControlTemplate.Resources>
<Style x:Key="WishlistBorderContent" TargetType="Border">
<Setter Property="BorderThickness" Value="0 0 0 2"/>
<Setter Property="BorderBrush" Value="#50D3D3D3"/>
</Style>
</ControlTemplate.Resources>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="WishlistBorder" Property="BorderThickness" Value="2"/>
<Setter TargetName="WishlistBorder" Property="BorderBrush" Value="#63C5DA"/>
<Setter Property="Foreground" Value="Red"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="WishlistBorder" Property="Background" Value="#50D3D3D3"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<ListBox ItemsSource="{Binding SymbolList}" SelectedItem="{Binding SelectedSymbol}"
Style="{StaticResource WishlistListBoxStyle}" HorizontalContentAlignment="Stretch" Width="200" Padding="0">
<ListBox.ItemTemplate>
<DataTemplate>
<Label Content="{Binding}" Foreground="White"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Reference Button Name in DataTrigger

I have a styled button as follow :
<Style x:Key="btnDefaultOperationImage" TargetType="{x:Type Button}">
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="brdMenu"
BorderThickness="0"
Padding="4,2"
BorderBrush="White"
Background="#20000000">
<StackPanel>
<ContentPresenter x:Name="ButtonContentPresenter" VerticalAlignment="Center" HorizontalAlignment="Center">
<ContentPresenter.Resources>
<Style TargetType="TextBlock">
<Setter Property="TextAlignment" Value="Center" />
</Style>
</ContentPresenter.Resources>
</ContentPresenter>
<Image>
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="/Images/Icons/CourtHearing.png" />
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}, Path=Name}" Value="btnCases">
<Setter Property="Source" Value="/Images/Icons/Cases.png"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="brdMenu" Property="BorderBrush" Value="#F2826A"/>
<Setter TargetName="brdMenu" Property="Background" Value="#30000000"/>
<Setter TargetName="brdMenu" Property="TextElement.FontSize" Value="25"/>
<Setter TargetName="brdMenu" Property="TextElement.Foreground" Value="AntiqueWhite"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="brdMenu" Property="BorderBrush" Value="OrangeRed" />
<Setter TargetName="brdMenu" Property="Background" Value="White" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<!--<Setter TargetName="brdMenu" Property="Background" Value="{StaticResource DisabledBackgroundBrush}" />-->
<Setter TargetName="brdMenu" Property="Background" Value="#f9f9f9" />
<Setter TargetName="brdMenu" Property="Opacity" Value="0.3" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I want to use this style on many buttons, but each button will have a different image according to it name, for example :
The Button Name="btnCases" the ImageSource="..\..\Cases.png"
The Button Name="btnActors" the ImageSource="..\..\Actors.png"
I am wondering if it 's possible to use DataTrigger to solve this issue, i tried
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}, Path=Name}" Value="btnCases">
But it doesn't work.
I think you're asking for something like this. What you need to do is bind your image source to a property on each button. I've used the tag property in this example, but you could use anything - attached property, ViewModel property etc..
<Window.Resources>
<Style x:Key="btnDefaultOperationImage" TargetType="{x:Type Button}">
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="brdMenu"
BorderThickness="0"
Padding="4,2"
BorderBrush="White"
Background="#20000000">
<StackPanel>
<ContentPresenter x:Name="ButtonContentPresenter" VerticalAlignment="Center" HorizontalAlignment="Center">
<ContentPresenter.Resources>
<Style TargetType="TextBlock">
<Setter Property="TextAlignment" Value="Center" />
</Style>
</ContentPresenter.Resources>
</ContentPresenter>
<Image>
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="{Binding Tag, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" />
</Style>
</Image.Style>
</Image>
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="brdMenu" Property="BorderBrush" Value="#F2826A"/>
<Setter TargetName="brdMenu" Property="Background" Value="#30000000"/>
<Setter TargetName="brdMenu" Property="TextElement.FontSize" Value="25"/>
<Setter TargetName="brdMenu" Property="TextElement.Foreground" Value="AntiqueWhite"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="brdMenu" Property="BorderBrush" Value="OrangeRed" />
<Setter TargetName="brdMenu" Property="Background" Value="White" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<!--<Setter TargetName="brdMenu" Property="Background" Value="{StaticResource DisabledBackgroundBrush}" />-->
<Setter TargetName="brdMenu" Property="Background" Value="#f9f9f9" />
<Setter TargetName="brdMenu" Property="Opacity" Value="0.3" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<StackPanel>
<Button Style="{StaticResource btnDefaultOperationImage}" Tag="..\image1.png"/>
<Button Style="{StaticResource btnDefaultOperationImage}" Tag="..\image2.png"/>
</StackPanel>
</Grid>
You can also use Converter
Assuming:
1) Every button is prepend with Btn
2) image is of only one format
<Image Source="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Button}},Path=Name,Converter=
{StaticResource NameToPathConverter}}"/>
then your button will look like:
<Button Name="BtnDestinationPin" Style="{StaticResource btnDefaultOperationImage}" />
Define Converter as a resource:
<local:NameToPathConverter x:Key="NameToPathConverter"/>
Code:
public class NameToPathConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string imageName = value.ToString().Substring(3);
return new BitmapImage(new Uri("pack://application:,,,/YourNamespace;component/Images/" + imageName + ".png"));
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

Style Basedon not working with checkbox

I have a style defined in a resource dictionary to make my checkbox look like a button:
<Style TargetType="CheckBox" x:Key="CBCheckBoxButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Border Name="BackgroundBorder" Background="Black" CornerRadius="20">
<Grid>
<Rectangle x:Name="UpperRect" Margin="1" Grid.Row="0" RadiusX="20" RadiusY="20" Fill="{StaticResource GrayGradient}"/>
<TextBlock Name="ButtonContent" Text="{TemplateBinding Content}" Margin="3" VerticalAlignment="Center" TextAlignment="Center" TextWrapping="Wrap" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="UpperRect" Property="Fill" Value="{StaticResource LightBlueGradient}" />
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="UpperRect" Property="Fill" Value="{StaticResource BlueGradient}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="BackgroundBorder" Property="Background" Value="DarkGray"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Effect" Value="{StaticResource ShadowEffect}" />
<Setter Property="FontSize" Value="14"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="FontFamily" Value="Calibri"/>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="DarkGray"/>
<Setter Property="Effect" Value="{StaticResource DisableShadowEffect}" />
</Trigger>
</Style.Triggers>
</Style>
When used like so it works great:
<CheckBox Width="80" Height="80" Margin="10" Content="{Binding Y2LockAxisString}" Command="{Binding Y2LockDisableEnableCommand}" Style="{StaticResource CBCheckBoxButton}"/>
But I need to add a style so that different commands etc. are called depending on the state of the check box. So I used the basedon property:
<CheckBox Width="80" Height="80" Margin="10">
<Style TargetType="{x:Type CheckBox}" BasedOn="{StaticResource CBCheckBoxButton}">
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Command" Value="{Binding ExecuteX2LockDisable}" />
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Command" Value="{Binding ExecuteX2LockEnable}" />
</Trigger>
</Style.Triggers>
</Style>
</CheckBox>
But the checkbox looks like a default checkbox with none of the appearance elements applied to it.
Why isn't the appearance style working?
It seems you are adding the Style as Content, instead of Style.
Have you tried
<CheckBox Width="80" Height="80" Margin="10">
<CheckBox.Style>
<Style --- snip --->
</Style>
</CheckBox.Style>
</CheckBox>

RadDropDownButton.DropDownContent as a RadButton - cannot change highlight color

Here is my xaml code...
The hover color is still that yellow goldish out of the box color... Am I doing something wrong. I want to change it so that I can specify the mouse over color.
<telerik:RadDropDownButton Height="16" HorizontalAlignment="Left" IsOpen="False" Margin="999,16,0,0" Name="RDDLocations" VerticalAlignment="Top" Width="15" Content=" " Background="#FF25B7DB" Foreground="White" BorderThickness="0">
<telerik:RadDropDownButton.DropDownContent>
<telerik:RadListBox x:Name="UIOptionsList" ItemsSource="{Binding LocationItems}" Background="#FF25B7DB">
<telerik:RadListBox.ItemTemplate>
<DataTemplate>
<telerik:RadButton>
<telerik:RadButton.Style>
<Style TargetType="telerik:RadButton">
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="Height" Value="32"/>
<Setter Property="Width" Value="200"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontFamily" Value="Franklin Gothic Book"/>
<Setter Property="FontSize" Value="16"/>
<Setter Property="Content" Value="{Binding Text}"/>
<Setter Property="ToolTip" Value="{Binding ToolTip}"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Background" Value="Transparent"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FF25B7DB"/>
<Setter Property="Foreground" Value="Orange"/>
</Trigger>
</Style.Triggers>
</Style>
</telerik:RadButton.Style>
</telerik:RadButton>
</DataTemplate>
</telerik:RadListBox.ItemTemplate>
</telerik:RadListBox>
</telerik:RadDropDownButton.DropDownContent>
</telerik:RadDropDownButton>
My solution was to use a regular button instead of a telerik radbutton.

How To Style Button's Hover And Click Foreground?

I am new to Styles and not sure on the best way to create a Button style to change the Foreground of IsMouseOver and IsPressed. I used a Border for a template because it has a CornerRadius and background and border properties. But Border does not have a Foreground property. Using Button as the template doesn't work well since the default look isn't being overridden.
What is a better way to style a Button template with Foreground behavior? Maybe using a label inside the border?
Here is the App.xaml:
<Application.Resources>
<Style TargetType="Button" x:Key="MyButton">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="MinHeight" Value="34"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="shortcutbutton"
BorderThickness="1"
BorderBrush="Black"
Background="Gray">
<ContentPresenter Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="shortcutbutton" Property="Background" Value="#FFDADADA" />
<Setter TargetName="shortcutbutton" Property="BorderBrush" Value="#EEEEEE" />
<!--<Setter TargetName="Border" Property="Foreground" Value="Black" />-->
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="shortcutbutton" Property="Background" Value="DarkGray" />
<Setter TargetName="shortcutbutton" Property="BorderBrush" Value="Black" />
<!--<Setter TargetName="Border" Property="Foreground" Value="Red" />-->
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
And the xaml:
<StackPanel HorizontalAlignment="Center" Height="100" VerticalAlignment="Center" Width="100">
<Button Content="Button" Height="41" Style="{DynamicResource MyButton}"/>
</StackPanel>
You need to move your Triggers from the ControlTemplate to the Style. Something like this:
<Style TargetType="Button">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="MinHeight" Value="34"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="shortcutbutton"
BorderThickness="1"
BorderBrush="Black"
Background="Gray">
<ContentPresenter Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Foreground" Value="#FFDADADA" />
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Foreground" Value="DarkGray" />
</Trigger>
</Style.Triggers>
</Style>
What you can do is set attached property of TextElement on the Border and like that every text element within your Border will be of that colour:
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="shortcutbutton" Property="Background" Value="#FFDADADA" />
<Setter TargetName="shortcutbutton" Property="BorderBrush" Value="#EEEEEE" />
<Setter TargetName="shortcutbutton" Property="TextElement.Foreground" Value="White"/>
</Trigger>
...
</ControlTemplate.Triggers>

Categories