How to increase size of scrollbar on hover using XAML - wpf

How to expand the width of the vertical/horizontal scroll when the user hovers over it, and then shrink it when it is not over it using WPF for VB.Net?
This way, it's easy to grab when it's needed, but doesn't take up too much space when it's not needed. I'm not quite aware about how to do it.
<Style x:Key="{x:Type ScrollBar}" TargetType="{x:Type ScrollBar}">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="1.2" />
<Setter Property="Height" Value="50"/> //Trying to set height of scrollbar here
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Opacity" Value="0.4" />
</Trigger>
<Trigger Property="Orientation" Value="Horizontal">
<Setter Property="Width" Value="Auto"/>
<Setter Property="Height" Value="10" />
<Setter Property="Template"
Value="{StaticResource HorizontalScrollBar}" />
</Trigger>
<Trigger Property="Orientation" Value="Vertical">
<Setter Property="Width" Value="10"/>
<Setter Property="Height" Value="Auto" />
<Setter Property="Template"
Value="{StaticResource VerticalScrollBar}" />
</Trigger>
</Style.Triggers>
</Style>

You must use a MultiTrigger and trigger on IsMouseOver based on orientation. The example sets width/height to 8 and 18 on mouse over:
<Style x:Key="{x:Type ScrollBar}" TargetType="{x:Type ScrollBar}">
<Setter Property="UseLayoutRounding" Value="True" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Orientation" Value="Horizontal" />
<Condition Property="IsMouseOver" Value="False" />
</MultiTrigger.Conditions>
<Setter Property="Width" Value="Auto" />
<Setter Property="Height" Value="8" />
<Setter Property="Template" Value="{StaticResource HorizontalScrollBar}" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Orientation" Value="Horizontal" />
<Condition Property="IsMouseOver" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Width" Value="Auto" />
<Setter Property="Height" Value="18" />
<Setter Property="Template" Value="{StaticResource HorizontalScrollBar}" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Orientation" Value="Vertical" />
<Condition Property="IsMouseOver" Value="False" />
</MultiTrigger.Conditions>
<Setter Property="Height" Value="Auto" />
<Setter Property="Width" Value="8" />
<Setter Property="Template" Value="{StaticResource VerticalScrollBar}" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Orientation" Value="Vertical" />
<Condition Property="IsMouseOver" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Height" Value="Auto" />
<Setter Property="Width" Value="18" />
<Setter Property="Template" Value="{StaticResource VerticalScrollBar}" />
</MultiTrigger>
</Style.Triggers>
</Style>

Related

How Remove Border around a DatagridTextCell that appears on VerticalAlignment = Center?

I want to display datevalues in a DataGrid, whereas the text is vertically aligned in the center of the row, and not at the top. If I change the VerticalAlignment property in the DataGridCell Style, the text is aligned correctly, but a frame appears. Setting BorderThickness to 0 does not fix this.
How can I get rid of the frame/border and also display the text in the middle of the row?
DataGrid Style
<Style x:Key="StandardTabelle" TargetType="{x:Type DataGrid}">
<Setter Property="Margin" Value="5"/>
<Setter Property="Background" Value="White"/>
<Setter Property="AlternatingRowBackground" Value="#ebecec"/>
<Setter Property="FontSize" Value="12" />
<Setter Property="RowHeight" Value="24"/>
<Setter Property="ColumnHeaderStyle" Value="{StaticResource StandardSpaltenKopf}" />
<Setter Property="CanUserAddRows" Value="False"/>
<Setter Property="CanUserDeleteRows" Value="False"/>
<Setter Property="CanUserReorderColumns" Value="False"/>
<Setter Property="CanUserResizeRows" Value="False"/>
<Setter Property="CanUserResizeColumns" Value="False"/>
<Setter Property="IsReadOnly" Value="True" />
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="RowStyle" Value="{StaticResource AusgewählteZeile}"/>
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
Style for selected Row
<Style x:Key="AusgewählteZeile" TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{StaticResource Rot}"/>
</Trigger>
</Style.Triggers>
</Style>
Style for Datecell with top alignment
<Style x:Key="DatumZelle" TargetType="DataGridCell">
<Setter Property="HorizontalContentAlignment" Value="Right"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="BorderThickness" Value="0"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Transparent" />
</Trigger>
</Style.Triggers>
</Style>
You could create a custom ControlTemplate:
<Style x:Key="DatumZelle" TargetType="DataGridCell">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Right" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Transparent" />
</Trigger>
</Style.Triggers>
</Style>

Trigger in Trigger

Is it possible to do this? I want to set IsMouseOver when there's a validation error occur.
<Style x:Key="textBoxInError"
TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError"
Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(Validation.Errors)[0].ErrorContent}" />
<Setter Property="BorderThickness"
Value="3" />
<Setter Property="BorderBrush"
Value="Red" />
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="BorderBrush"
Value="Red" />
</Trigger>
</Trigger>
</Style.Triggers>
</Style>
A MultiTrigger can contain multiple conditions.

TabItem BorderBrush not updating on IsMouseOver trigger

I have a MultiDataTrigger where if a property in my view model is true AND the IsMouseOver on the TabItem is true, then the Border should appear red with 2.5 thickness.
I couldn't get both the property and IsMouseOver to work, so I tried just my property. That worked correctly, but still had the expected issue where it would be red with 2.5 thickness, up until I hovered over the tab. So I then tried taking out my view model property and just had the IsMouseOver check as a condition. This doesn't work. Below is the code with just the IsMouseOver.
<TabItem x:Name="TabItemNotWorking" Header="NotWorking">
<TabItem.Style>
<Style TargetType="TabItem">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsMouseOver RelativeSource={RelativeSource Self}}" Value="true" />
<!--<Condition Binding="{Binding Counter, Converter={StaticResource IntIsGreaterThanZeroToBool}}" Value="true" />-->
</MultiDataTrigger.Conditions>
<Setter Property="TabItem.BorderBrush" Value="Red"/>
<Setter Property="TabItem.BorderThickness" Value="2.5"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</TabItem.Style>
<!--Content in here-->
</TabItem>
I fixed it using Mike Strobel's advice of overwriting the TabItem template. Now my red border will show whenever my ViewModel property is true, regardless if the mouser is hovered over the TabItem. Here is my solution (I put comments around the areas of code I modified):
<LinearGradientBrush x:Key="TabItemHotBackground"
StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#EAF6FD"
Offset="0.15"/>
<GradientStop Color="#D9F0FC"
Offset=".5"/>
<GradientStop Color="#BEE6FD"
Offset=".5"/>
<GradientStop Color="#A7D9F5"
Offset="1"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<SolidColorBrush x:Key="TabItemSelectedBackground"
Color="#F9F9F9"/>
<SolidColorBrush x:Key="TabItemDisabledBackground"
Color="#F4F4F4"/>
<SolidColorBrush x:Key="TabItemHotBorderBrush"
Color="#3C7FB1"/>
<SolidColorBrush x:Key="TabItemDisabledBorderBrush"
Color="#FFC9C7BA"/>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid SnapsToDevicePixels="true">
<Border Name="Bd"
Padding="{TemplateBinding Padding}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}"
BorderThickness="1,1,1,0">
<ContentPresenter Name="Content"
ContentSource="Header"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
HorizontalAlignment="{Binding Path=HorizontalContentAlignment,RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
VerticalAlignment="{Binding Path=VerticalContentAlignment,RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
RecognizesAccessKey="True"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Bd" Property="Background" Value="{StaticResource TabItemHotBackground}"/>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Panel.ZIndex" Value="1"/>
<Setter TargetName="Bd" Property="Background" Value="{StaticResource TabItemSelectedBackground}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="false"/>
<Condition Property="IsMouseOver" Value="true"/>
</MultiTrigger.Conditions>
<Setter TargetName="Bd" Property="BorderBrush" Value="{StaticResource TabItemHotBorderBrush}"/>
</MultiTrigger>
<!--HERE ARE THE START OF MY CHANGES-->
<DataTrigger Binding="{Binding Counter, Converter={StaticResource IntIsGreaterThanZeroToBool}}" Value="true">
<Setter TargetName="Bd" Property="BorderBrush" Value="Red"/>
<Setter TargetName="Bd" Property="BorderThickness" Value="2.5"/>
</DataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type TabItem}}}" Value="true" />
<Condition Binding="{Binding Counter, Converter={StaticResource IntIsGreaterThanZeroToBool}}" Value="true" />
</MultiDataTrigger.Conditions>
<Setter TargetName="Bd" Property="BorderBrush" Value="Red"/>
<Setter TargetName="Bd" Property="BorderThickness" Value="2.5"/>
</MultiDataTrigger>
<!--HERE ARE THE END OF MY CHANGES-->
<Trigger Property="TabStripPlacement" Value="Bottom">
<Setter TargetName="Bd" Property="BorderThickness" Value="1,0,1,1"/>
</Trigger>
<Trigger Property="TabStripPlacement" Value="Left">
<Setter TargetName="Bd" Property="BorderThickness" Value="1,1,0,1"/>
</Trigger>
<Trigger Property="TabStripPlacement" Value="Right">
<Setter TargetName="Bd" Property="BorderThickness" Value="0,1,1,1"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="TabStripPlacement" Value="Top"/>
</MultiTrigger.Conditions>
<Setter Property="Margin" Value="-2,-2,-2,-1"/>
<Setter TargetName="Content" Property="Margin" Value="0,0,0,1"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="TabStripPlacement" Value="Bottom"/>
</MultiTrigger.Conditions>
<Setter Property="Margin" Value="-2,-1,-2,-2"/>
<Setter TargetName="Content" Property="Margin" Value="0,1,0,0"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="TabStripPlacement" Value="Left"/>
</MultiTrigger.Conditions>
<Setter Property="Margin" Value="-2,-2,-1,-2"/>
<Setter TargetName="Content" Property="Margin" Value="0,0,1,0"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="TabStripPlacement" Value="Right"/>
</MultiTrigger.Conditions>
<Setter Property="Margin" Value="-1,-2,-2,-2"/>
<Setter TargetName="Content" Property="Margin" Value="1,0,0,0"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Bd" Property="Background" Value="{StaticResource TabItemDisabledBackground}"/>
<Setter TargetName="Bd" Property="BorderBrush" Value="{StaticResource TabItemDisabledBorderBrush}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
You will notice that the following condition works, but only when the tab is selected:
<Condition Binding="{Binding IsMouseOver RelativeSource={RelativeSource Self}}"
Value="true" />
Here's why: note this excerpt from the default TabItem template for the Aero theme.
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected"
Value="false"/>
<Condition Property="IsMouseOver"
Value="true"/>
</MultiTrigger.Conditions>
<Setter TargetName="Bd"
Property="BorderBrush"
Value="{StaticResource TabItemHotBorderBrush}"/>
</MultiTrigger>
The style overrides the BorderBrush on mouse-over when the tab isn't selected, so your border brush won't be applied in that case.
Since the setter uses a StaticResource to reference TabItemHotBorderBrush, you can't simply override this resource with your own brush. You will probably have to override the default template.

DatagridRow's mouseover not working properly

I have the following styles for my datagrid :
<Style x:Key="StyleDataGrid" TargetType="{x:Type DataGrid}">
<Setter Property="SelectionMode" Value="Single" />
<Setter Property="SelectionUnit" Value="FullRow" />
<Setter Property="CanUserAddRows" Value="False" />
<Setter Property="AutoGenerateColumns" Value="False" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="CanUserResizeColumns" Value="True" />
<Setter Property="GridLinesVisibility" Value="Horizontal" />
<Setter Property="HorizontalGridLinesBrush" Value="Black" />
<Setter Property="CanUserReorderColumns" Value="False" />
<Setter Property="HeadersVisibility" Value="Column" />
<Setter Property="CanUserDeleteRows" Value="False" />
<Setter Property="Padding" Value="8"/>
</Style>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Padding" Value="5" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="FontSize" Value="14" />
<Setter Property="FontFamily" Value="Helvetica" />
<Setter Property="Foreground" Value="Black"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Border Padding="{TemplateBinding Padding}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
<ContentPresenter.ContentTemplate>
<DataTemplate>
<TextBlock Background="Transparent" Name="text" TextTrimming="CharacterEllipsis"
Height="auto" Width="auto" Text="{Binding Text}"/>
</DataTemplate>
</ContentPresenter.ContentTemplate>
</ContentPresenter>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Red"/>
<Setter Property="Foreground" Value="White" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<!--<Setter Property="ToolTip" Value="{Binding Content.Text, RelativeSource={RelativeSource Self}}"/>-->
<Setter Property="Background" Value="Orange"/>
<Setter Property="Foreground" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="Margin" Value="0"/>
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Background" Value="{StaticResource CouleurFond}" />
<Setter Property="Foreground" Value="{StaticResource ResourceKey=CouleurTexte}" />
<Setter Property="Padding" Value="5"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Red"/>
<Setter Property="Foreground" Value="White" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Orange"/>
<Setter Property="Foreground" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
But the mouseOver event on my DataGridRow doesn't work. When My mouse is over a row, the row 's Background is red but the text's foreground remains Black on all my columns excepted the cell under my mouse where the text became white as expected.
But I'd like to have all my line's foreground white when my mouse is over a row. What is wrong with my styles ?
Thank you
The trick was to add these lines to manage the mouse over event of my DataGridCell:
<DataTrigger Binding="{Binding Path=IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}" Value="True">
<Setter Property="Background" Value="{StaticResource ResourceKey=CouleurBoutonHover}"/>
<Setter Property="Foreground" Value="{StaticResource ResourceKey=CouleurTexteBoutonHover}" />
</DataTrigger>
and it was working :)
If you comment out your other Styles temporarily, you'll see that actually, your DataGridRow Style works just fine... the Background of the selected DataGridRow is Orange as you required:
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="Margin" Value="0"/>
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Background" Value="{StaticResource CouleurFond}" />
<Setter Property="Foreground" Value="{StaticResource ResourceKey=CouleurTexte}" />
<Setter Property="Padding" Value="5"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Red"/>
<Setter Property="Foreground" Value="White" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Orange"/>
<Setter Property="Foreground" Value="White" />
</Trigger>
</Style.Triggers>
</Style
Therefore, you need to set your other Styles more carefully. Add them part by part and keep running the program occasionally to check that your problem hasn't reappeared and if it has, just undo the last edit or two, as that was what was causing your problem.
UPDATE >>>
Please read my last paragraph again:
you need to set your other Styles more carefully. Add them part by part and keep running the program occasionally to check that your problem hasn't reappeared and if it has, just undo the last edit or two, as that was what was causing your problem.
Add them part by part does not mean add the whole DataGridCell Style back in one go as you clearly have done. If you had added the setters back into the DataGridCell Style part by part then you would have noticed which setter is causing the problem for you.

Datagrid hover not working with alternate row colors - wpf

This works just fine with DataGridRow..
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="{StaticResource RolloverBrush}" />
<Setter Property="Foreground" Value="#000" />
</Trigger>
But when I add these, the mouse-over styles don't work..
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="{StaticResource LightRowBrush0}" />
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="{StaticResource LightRowBrush1}" />
</Trigger>
The order of the styles matter.
Applying the alternation triggers before the others worked.
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="{StaticResource LightRowBrush0}" />
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="{StaticResource LightRowBrush1}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="{StaticResource RolloverBrush}" />
<Setter Property="Foreground" Value="#000" />
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" Value="{StaticResource SelectedBrush}" />
<Setter Property="Foreground" Value="#000" />
</Trigger>
</Style.Triggers>

Resources