Apply style on mouseover and when class variable is true - wpf

I come from a web background, so I'm really struggling with this one.
I have a style that I need applied when both IsMouseOver is true and a class variable (called _isLinking) is true within my Linking class is true also. I have the style built and functioning with the IsMouseOver, but I'm not sure how to get the second condition with the _isLinking in there.
<Path.Style>
<Style>
<Setter Property="Path.Stroke" Value="Black" />
<Setter Property="Path.Fill" Value="LightGray" />
<Style.Triggers>
<Trigger Property="Canvas.IsMouseOver" Value="True">
<Setter Property="Path.Stroke" Value="Blue" />
<Setter Property="Path.Fill" Value="LightBlue" />
</Trigger>
</Style.Triggers>
</Style>
</Path.Style>

You should use MultiDataTrigger (msdn).
Example:
<Canvas>
<Path>
<Path.Data>
<PathGeometry Figures="M 10,100 C 10,300 300,-200 300,100" />
</Path.Data>
<Path.Style>
<Style>
<Setter Property="Path.Stroke" Value="Black" />
<Setter Property="Path.Fill" Value="LightGray" />
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Canvas}}" Value="True" />
<Condition Binding="{Binding IsLinking}" Value="True" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="Path.Stroke" Value="Blue" />
<Setter Property="Path.Fill" Value="LightBlue" />
</MultiDataTrigger.Setters>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Path.Style>
</Path>
</Canvas>
In the above example DataContext is set to object of type Linking.
this.DataContext = new Linking { IsLinking = true };

Related

How to change IsMouseOver style based on DataTrigger?

This code below changes the background on all states. How to change background to blue only when both IsMouseOver and DataTrigger is true?
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" TargetName="Target1" Value="Red" />
</Trigger>
<DataTrigger Binding = "{Binding ElementName = Import, Path = IsEnabled}" Value="true">
<Setter Property="Background" TargetName="Target1" Value="Blue" />
</DataTrigger>
</ControlTemplate.Triggers>
You can do a MultiDataTrigger. Something like:
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsEnabled}" Value="True" />
<Condition Binding="{Binding IsMouseOver}" Value="True" />
</MultiDataTrigger.Conditions>
<Setter Property="...." Value="...." />
</MultiDataTrigger>

DataTrigger inside a MultiDataTrigger?

I want to change 2 Properties on 2 different conditions using Multi-/DataTrigger.
I have 1 Button which changes its IsEnabled Property when ValidationRule returns an error.
I also want to change the Command Property of this Button but on other conditions.
<Button Content="Save">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource MaterialDesignFlatButton}">
<Setter Property="IsEnabled" Value="False" />
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=(Validation.HasError), ElementName=FirstNameBox}" Value="False" />
<Condition Binding="{Binding Path=(Validation.HasError), ElementName=LastNameBox}" Value="False" />
[...]
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="True" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Now I want to implement another Trigger which changes the Binding of the Command Property when anoither Propertie's Binding equals to XY.
So i need to implement this next to the Datatrigger above.
<Setter Property="Command" Value="{Binding CreateEmployeeCommand}" />
<DataTrigger Binding="{Binding CurrentManageMode}" Value="2">
<Setter Property="Command" Value="{Binding EditEmployeeCommand}" />
</DataTrigger>
So is it even possible to have 2 Triggers at the same time?
Okay, i fixed it adding another Trigger just in Style.Triggers.
I didn't tried this cuz many Controls/Properties doesn't allow multiple Content.
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource MaterialDesignFlatButton}">
<Setter Property="IsEnabled" Value="False" />
<Setter Property="Command" Value="{Binding CreateEmployeeCommand}" />
<Style.Triggers>
<DataTrigger Binding="{Binding CurrentManageMode}" Value="2">
<Setter Property="Command" Value="{Binding EditEmployeeCommand}" />
</DataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=(Validation.HasError), ElementName=FirstNameBox}" Value="False" />
<Condition Binding="{Binding Path=(Validation.HasError), ElementName=LastNameBox}" Value="False" />
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="True" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Button.Style>

Computed Setter Value based on existing value - WPF

Currently have a setup as below:
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="rectName" Property="Stroke" Value="Red"/>
<Setter TargetName="rectName" Property="StrokeThickness" Value="2"/>
</Trigger>
i.e. The trigger changes the Stroke and Thickness of a Rectangle to Red and 2 on MouseOver.
But this must happen only when the Rectangle's Stroke is Black (Few rectangles have transparent stroke)
Is there any way to put this condition on Setter? I'm looking at a less intrusive way of accomplishing this. Any leads?
Is there a construct something like below:
<Setter TargetName="rectName" Property="Stroke" Value="If Black Then Black Else Red"/>
Here this will work, note however this code will throw a stack overflow exception because of the change of the changing colors when you mouse over ie red black red black and so on :/ I would just suggest some other way to keep track of the rect state, maybe a variable in the ViewModel that keeps track of the state and and in the code replace:
<Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=Stroke}" Value="Black" />
With something like:
<Condition Binding="{Path=RectState}" Value="True" />
Otherwise this will crash :) (Sorry writing this in a rush)
<Rectangle Height="100" HorizontalAlignment="Left" Margin="182,152,0,0" Name="rectangle1" VerticalAlignment="Top" Width="200" >
<Rectangle.Style>
<Style TargetType="Rectangle">
<Setter Property="Fill" Value="Transparent" />
<Setter Property="Stroke" Value="Black" />
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsMouseOver}" Value="True" />
<Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=Stroke}" Value="Black" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="StrokeThickness" Value="2" />
<Setter Property="Stroke" Value="Red" />
</MultiDataTrigger.Setters>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
You can achieve this using MultiTrigger (code below not tested, but should be close enough)
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="Stroke" Value="Black" />
</MultiTrigger.Conditions>
<Setter TargetName="rectName" Property="Stroke" Value="Red" />
<Setter TargetName="rectName" Property="StrokeThickness" Value="2" />
</MultiTrigger>
</Style.Triggers>

Change background on WPF Listview item when it's selected

I have a WPF Listview, and I have overridden the ListView.ItemTemplate to change the background color of the items on the ListViewItem.IsMouseOver event like so:
<AlternationConverter x:Key="BackgroundConverter">
<SolidColorBrush>White</SolidColorBrush>
<SolidColorBrush>
<SolidColorBrush.Color>
<Color A="242" R="242" G="242" B="242" />
</SolidColorBrush.Color>
</SolidColorBrush>
</AlternationConverter>
<Style x:Key="alternatingWithBinding" TargetType="{x:Type ListViewItem}">
<Setter Property="Height" Value="31"/>
<Setter Property="Background"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(ItemsControl.AlternationIndex),
Converter={StaticResource BackgroundConverter}}"/>
<Style.Triggers>
<Trigger Property="ListViewItem.IsSelected" Value="True">
<Setter Property="ListViewItem.Background" Value="Yellow" />
</Trigger>
<Trigger Property="ListBoxItem.IsMouseOver" Value="True">
<Setter Property="ListBoxItem.Background" Value="Blue" />
</Trigger>
</Style.Triggers>
</Style>
What I'm trying to achieve is to have a different color when hovered over the already selected item (which is yellow). So on all the items it will be a Blue hover-over, and on the selected Yellow item, it'll be green.
I tried the below attempt, using MultiTrigger, but that didn't do the trick:
<Style x:Key="alternatingWithBinding" TargetType="{x:Type ListViewItem}">
<Setter Property="Height" Value="31"/>
<Setter Property="Background"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(ItemsControl.AlternationIndex),
Converter={StaticResource BackgroundConverter}}"/>
<Style.Triggers>
<Trigger Property="ListViewItem.IsSelected" Value="True">
<Setter Property="ListViewItem.Background" Value="Yellow" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="ListBoxItem.IsMouseOver" Value="True"/>
<Condition Property="ListBoxItem.IsSelected" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="ListBoxItem.Background" Value="Green" />
</MultiTrigger>
<Trigger Property="ListBoxItem.IsMouseOver" Value="True">
<Setter Property="ListBoxItem.Background" Value="Blue" />
</Trigger>
</Style.Triggers>
</Style>
Any ideas?
Thanks.
Are the triggers are applied in order? It might work if you move the MultiTrigger to the bottom, then it will apply after the IsMouseOver Trigger.

wpf Treeview CheckBox Item ForeGround Color cannot Change when it is disabled?

This is the my xaml style for Treeview CheckBox Item. I'm using Syncfusion Treeview.
<Style x:Key="contractListItemContainerStyle" TargetType="{x:Type syncfusion:TreeViewItemAdv}">
<Setter Property="IsExpanded" Value="True" />
<Setter Property="IsSelected" Value="{Binding IsInitiallySelected, Mode=OneTime}" />
<Setter Property="KeyboardNavigation.AcceptsReturn" Value="True" />
<Setter Property="IsEditable" Value="False" />
<Setter Property="IsEnabled" Value="{Binding Enable}" />
<Setter Property="Foreground" Value="Red" />
<Style.Triggers>
<Trigger Property="IsEnabled" Value="True">
<Setter Property="Foreground" Value="Green" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
<HierarchicalDataTemplate x:Key="selectedContractsDataTemplate" ItemsSource="{Binding Children}" >
<StackPanel Orientation="Horizontal">
<CheckBox Margin="2,0,2,0"
Focusable="False"
IsChecked="{Binding Content.IsChecked}"
VerticalAlignment="Center" />
<ContentPresenter Content="{Binding}" Margin="2,0" />
</StackPanel>
</HierarchicalDataTemplate>
If I set Enable to False from ViewModel, The Color doesn't change to red but If I set to true, it changes to Green. Why? Pelase advise.
The code should work, see/try this:
<StackPanel>
<CheckBox Name="chk" Content="check this...">
<CheckBox.Style>
<Style>
<Setter Property="CheckBox.Foreground" Value="Red" />
<Style.Triggers>
<Trigger Property="CheckBox.IsEnabled" Value="True">
<Setter Property="CheckBox.Foreground" Value="Green" />
</Trigger>
<Trigger Property="CheckBox.IsEnabled" Value="False">
<Setter Property="CheckBox.Foreground" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>
<Button Content="press" Click="Button_Click"/>
</StackPanel>
Probably something is wrong with the binding?
Try this
<Setter Property = "Foreground" Value = "Red"/>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="True">
<Setter Property="Foreground" Value="Green" />
</Trigger>
</Style.Triggers>

Resources