How to increase ListViewItem Opacity on Mouseover? - wpf

I am dimming the Opacity on the custom control items in a ListView and would like to have them set back to full opacity OnMouseOver. I can dim them OnMouseOver, but I can not increase the Opacity. I am guessing it has something to do with the ListView ControlTemplate. Any help is appreciated it is getting very frustrating:
<ListView Background="Transparent" BorderBrush="Transparent" Grid.Row="0" VerticalAlignment="Top">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value=".9"/>
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
<notify:NotificationInfo/>
</ListView>

I don't know if this is useful:
<ListView>
<ListViewItem>Johan</ListViewItem>
<ListViewItem>Ray</ListViewItem>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value=".9"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Opacity" Value=".2"/>
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
</ListView>
Did not feel super nice.

Related

WPF, how to style TabItem basing on TabControl's property?

I want to achieve similar effect, which can be seen in Notepad++: dividing TabContol into two TabControls. Obviously both will have selected tab on their own, but still only one of them will be active.
For those who doesn't know Notepad++, this is how it looks like:
For that I'll need to introduce "Active" property on TabControl (not Focused, because when one of TabControls loses focus, its selected tab still remains active). However, I have no idea how to craft trigger on TabItem's ControlTemplate, which will allow me to distinguish selected and selected+active tab.
This is how my current TabItem template look:
<Style x:Key="BaseRootTabItem" TargetType="TabItem">
<Style.Setters>
<Setter Property="Background" Value="{StaticResource NormalTabBackgroundBrush}" />
<Setter Property="TextBlock.Foreground" Value="{StaticResource NormalTabForegroundBrush}" />
</Style.Setters>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.Setters>
<Setter Property="Background" Value="{StaticResource HoverTabBackgroundBrush}" />
<Setter Property="TextBlock.Foreground" Value="{StaticResource HoverTabForegroundBrush}" />
</Trigger.Setters>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="DocumentTabItem" TargetType="TabItem" BasedOn="{StaticResource BaseRootTabItem}">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabItem">
<Border x:Name="TabBorder" BorderThickness="1,1,1,0" BorderBrush="Transparent"
Background="{TemplateBinding Background}" TextBlock.Foreground="{TemplateBinding Foreground}">
<ContentPresenter x:Name="ContentSite" HorizontalAlignment="Center" VerticalAlignment="Center" ContentSource="Header" Margin="6,2" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Trigger.Setters>
<Setter Property="Background" Value="{StaticResource SelectedDocumentTabBackgroundBrush}" />
<Setter Property="Foreground" Value="{StaticResource SelectedDocumentTabForegroundBrush}" />
</Trigger.Setters>
</Trigger>
</Style.Triggers>
</Style>
I need something like:
<Trigger Property="(Owning TabControlEx's Active property)" Value="True">
<Trigger.Setters>
...
</Trigger.Setters>
</Trigger>
Or maybe there's some other solution?
Since Active property doesn't belong to TabItem, Trigger won't work. Use DataTrigger with binding to parent:
<DataTrigger Binding="{Binding Active, RelativeSource={RelativeSource AncestorType=TabControlEx}}"
Value="True">
</DataTrigger>

ListView without hover and selected style but with alternating listviewitem color style

I try to create a ListView which doesn't have a hover and selected style but has alternating colors for the ListViewItem's.
To disable the styles I set the ItemContainerStyle. The problem is that the expression ListView.AlternationIndex is somehow allways evaluating to 0 as Christian Mosers WPF Inspector tells me. This results in that the background color for all items is red.
<ListView ItemsSource="{Binding Configuration}" AlternationCount="2" >
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Border>
<Border.Style>
<Style TargetType="Border">
<Style.Triggers>
<Trigger Property="ListView.AlternationIndex" Value="0">
<Setter Property="Background" Value="Red" />
</Trigger>
<Trigger Property="ListView.AlternationIndex" Value="1">
<Setter Property="Background" Value="Blue" />
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<ContentPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
</ListView>
How can I color the items alternating wihout having the selected and hover style?
(The background color of the first item should be red the one of the second blue the one of the third red again and so on)
(The Backgroundcolor, border, padding, margin and so on should not change when the mouse is over an ListViewItem or a ListViewItem is selected)
EDIT: Thanks for the answers. I changed added a template binding to the solution to get rid of the Name property.
<ListView ItemsSource="{Binding Configuration}" AlternationCount="2" >
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Style.Triggers>
<Trigger Property="ListBox.AlternationIndex" Value="0">
<Setter Property="Border.Background" Value="Red" />
</Trigger>
<Trigger Property="ListBox.AlternationIndex" Value="1">
<Setter Property="Border.Background" Value="Blue" />
</Trigger>
</Style.Triggers>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Border Background="{TemplateBinding Background}">
<ContentPresenter Content="{TemplateBinding Content}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
</ListView>
Put the triggers in <ControlTemplate.Triggers>:
<ListView ItemsSource="{Binding Configuration}" AlternationCount="2" >
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Border x:Name="Border">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="Red" TargetName="Border" />
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="Blue" TargetName="Border" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
</ListView>
The triggers have to be on the control template; the Border doesn't know anything about its parent.
But since the property to set (Background) is on the Border, you have to name it and use TargetName.
<ListView AlternationCount="2" >
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Border Name="border">
<ContentPresenter/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" TargetName="border" Value="Red" />
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" TargetName="border" Value="Blue" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
<ListViewItem Content="ABC"/>
<ListViewItem Content="DEF"/>
<ListViewItem Content="GHI"/>
<ListViewItem Content="JKL"/>
</ListView>
This XAML produces the desired result:

Make text bold when mouse hovers over Context menu

I am wondering how to change the text when the mouse hovers over text in a context menu? I want the text to become Bold but not sure how to do this. Any help would be appreciated :). This is my resource style for the menu Items containing an image, which is where I think I should put it
XAML
<Style x:Key="MenuItemIcon" TargetType="MenuItem">
<Style.Resources>
<Style TargetType="ContentPresenter">
<Style.Triggers>
<Trigger Property="ContentSource" Value="Icon">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Image Source="{Binding}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Style.Resources>
</Style>
You can try following :
<Style TargetType="MenuItem" BasedOn="{StaticResource {x:Type MenuItem}}" x:Shared="False">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
Let me know if it works for you :)
Regards,
To answer your another question, to change hover background please use the following :
<Style TargetType="MenuItem" BasedOn="{StaticResource {x:Type MenuItem}}" x:Shared="False">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="Red" />
</Trigger>
</Style.Triggers>

How to sync two TextBlock's background?

I want to synchronize the background of two TextBlockes. For example, if the mouse is over any of the textblockes, I'd like to change the background color to the same for both textblockes. I know I can use this trigger to change one background:
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Background" Value="LightGray"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Gray"/>
</Trigger>
</Style.Triggers>
</Style>
But how to sync them?
UPDATE: this is not working either:
<UserControl.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Background" Value="LightGray"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Gray"/>
</Trigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Background="{Binding Path=Background, ElementName=tbHeader, Mode=TwoWay}" Text="A"/>
<TextBlock x:Name="tbHeader" Grid.Column="1" Text="B"/>
</Grid>
You can sync it by placing them in ContentControl and applying trigger on ControlTemplate like this -
<Grid>
<ContentControl>
<ContentControl.Template>
<ControlTemplate>
<StackPanel>
<TextBlock Text="Rohit" x:Name="txt1"/>
<TextBlock Text="Vats" x:Name="txt2"/>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="TextBlock.IsMouseOver" SourceName="txt1"
Value="True">
<Setter Property="TextBlock.Background" Value="Red"
TargetName="txt1"/>
<Setter Property="TextBlock.Background" Value="Red"
TargetName="txt2"/>
</Trigger>
<Trigger Property="TextBlock.IsMouseOver" SourceName="txt2"
Value="True">
<Setter Property="TextBlock.Background" Value="Red"
TargetName="txt1"/>
<Setter Property="TextBlock.Background" Value="Red"
TargetName="txt2"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ContentControl.Template>
</ContentControl>
</Grid>
Try element to element binding
<TextBlock x:Name=textBlock1>
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Background" Value="LightGray"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Gray"/>
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<TextBlock Background={Binding Path=Background ElementName=textBlock1/><!--Background gets set from textBlock1-->
If you are looking for the 'correct' MVVM way, you should bind the mouse-over events/properties to the same property of a view model, and the background to the same property again, with a converter to convert it to the appropriate colour (or a style with templates).

wpf datagrid alternate row coloring

I have tried this method.. without luck..
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Foreground" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
Is there a way to get the row Index?
I have even tried
<DataTrigger Binding="{Binding AlternationIndex}" Value="0">
<Setter Property="Foreground" Value="Green"></Setter>
</DataTrigger>
Finally, this is what I ended up with for generically setting alternate row colors.
<Style TargetType="{x:Type DataGrid}">
<Setter Property="Background" Value="#FFF" />
<Setter Property="AlternationCount" Value="2" />
</Style>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="#CCC"></Setter>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="#EEE"></Setter>
</Trigger>
</Style.Triggers>
</Style>
Unless already done, you have to set the AlternationCount property of DataGrid:
<DataGrid AlternationCount="2"
... />
You should additionally check whether the Foreground property is used for any Control in the DataGridRow. Try setting the Background property to test the alternation stuff.
Try setting the alternating background like this:
AlternationCount="2" AlternatingRowBackground="Bisque"
Try this
<DataGrid AlternationCount="2"
AlternatingRowBackground="Salmon" ........
Finally I used combination of Robin Maben and Th3G33k solution, because I want the alternation colour to override with my own, when some condition is met.
Thanks both.
<DataGrid x:Name="gridCustomerOrderItems" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" AutoGenerateColumns="False"
AlternationCount="2"
IsReadOnly="True" CanUserReorderColumns="True"
ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Auto">
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<!--first alteraniting colour-->
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="#EEE"></Setter>
</Trigger>
<!--then override with my own colour-->
<DataTrigger Binding="{Binding InvoiceSet}" Value="True">
<Setter Property="Background" Value="Green"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>

Resources