How to set Trigger from parent property to set child property - c#

I keep going around in circles on this data trigger so it is not working...
I have a button that has a border for a default dropshadow. However, I want to create a dep property to be used to toggle this. Yet, I never get to the point where the effect is being set.
<Style x:Key="RoundedButton" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ctrls:RoundedButton">
<Grid>
<Border>
<Border.Style>
<Style TargetType="ctrls:RoundedButton">
<Style.Triggers>
<Trigger Property="IsDropShadowVisible" Value="True">
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="1"/>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
This is based off of a button, but is implemented as the custom user control...This is legacy code...

What I have here works
Did this in a new WPF window. No other code-behind than what you see here.
<Window.Resources>
<Style TargetType="{x:Type local:ShadowButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ShadowButton}">
<Button Name="Button"></Button>
<ControlTemplate.Triggers>
<Trigger Property="IsDropShadowVisible" Value="True">
<Setter TargetName="Button" Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="1"/>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<!-- snip code -->
<local:ShadowButton Height="10" Width="10" IsDropShadowVisible="true"/>
Code-behind:
public class ShadowButton : Button
{
public DependencyProperty IsDropShadowVisibleProperty =
DependencyProperty.Register("IsDropShadowVisible", typeof(Boolean), typeof(ShadowButton), new PropertyMetadata(false));
public Boolean IsDropShadowVisible
{
get { return (Boolean)GetValue(IsDropShadowVisibleProperty); }
set { SetValue(IsDropShadowVisibleProperty, value); }
}
}

Related

Trigger not working on custom control image button wpf

I have created one custom cotrol
Generic.xaml code is below -
<BitmapImage x:Key="RightImaGE" x:Name="imgD" UriSource="/XYZ.UI_Test;components/Resources/Pfad55-1.png"/>
<Style TargetType="{x:Type local1:CustomButton}" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local1:CustomButton}">
<!--<Image Name="imgDefault" Source="{TemplateBinding Image}" Stretch="UniformToFill" />-->
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Path=ContentOff, RelativeSource={RelativeSource AncestorType=local1:CustomButton}}" Value="SETTINGS">
<Setter Property="Background" Value="Red"/>
<Setter Property="Image.Source" Value="{DynamicResource RightImaGE}" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
CustomButton.cs codebehind is below
public string ContentOff
{
get { return (string)GetValue(ContentOffProperty); }
set { SetValue(ContentOffProperty, value); }
}
public static readonly DependencyProperty ContentOffProperty =
DependencyProperty.Register("ContentOff",
typeof(string), typeof(CustomButton), new PropertyMetadata(null));
public ImageSource Image
{
get { return (ImageSource)GetValue(ImageProperty); }
set { SetValue(ImageProperty, value); }
}
public static readonly DependencyProperty ImageProperty =
DependencyProperty.Register("Image", typeof(ImageSource), typeof(CustomButton), new PropertyMetadata(default(ImageSource)));
I have defined one common style in app.xaml code is below
<Application.Resources>
<Style x:Key="BigButtonStyle" TargetType="local:CustomButton" >
<Setter Property="Control.Background" Value="Transparent"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="Margin" Value="1"/>
<Setter Property="FontSize" Value="27"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Foreground" Value="#1d5560"/>
<Setter Property="Width" Value="170"/>
<Setter Property="MaxHeight" Value="50"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomButton}">
<Canvas Margin="1">
<Image x:Name="img" Source="Resources/Pfad55.png" Stretch="UniformToFill" >
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="Resources/Pfad55.png" />
<!--<Style.Triggers>
--><!--<Trigger Property="ContentOff" Value="SETTINGS">
<Setter Property="Opacity" Value="0.5" />
</Trigger>--><!--
</Style.Triggers>-->
</Style>
</Image.Style>
</Image>
<ContentPresenter HorizontalAlignment="Center" Content="{TemplateBinding ContentOff}" Canvas.Top="14" Canvas.Left="47"
VerticalAlignment="Center"/>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Now I have Mainwindows.xaml where I am using Custombutton and if button content is Settings it should change different image through trigger than common image which is defined in bigbuttonstyle .
<Controls:CustomButton Grid.Row="8" Grid.Column="2" Style="{StaticResource BigButtonStyle}"
ContentOff="SETTINGS"
Image="Resources/Pfad55-1.png"/>
I tried to use data trigger here but not working and tried property trigger too. But image not changing somehow.
You can use two different style with style inheritance -
<Style x:Key="SmallButtonStyle" TargetType="local:CustomButton" BasedOn="{StaticResource BigButtonStyle}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomButton}">
<Canvas Margin="1">
<Image Source="Resources/Pfad55-1.png" Stretch="UniformToFill" ></Image>
<ContentPresenter HorizontalAlignment="Center" Content="{TemplateBinding ContentOff}" Canvas.Top="14" Canvas.Left="85"
VerticalAlignment="Center"/>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
then use it
<Controls:CustomButton Grid.Row="8" Grid.Column="2" Style="{StaticResource SmallButtonStyle}"
ContentOff="SETTINGS"
Image="Resources/Pfad55-1.png"/>
It'll be working but without trigger.
Another solution I have added based on your requirement.
Change your Generic.Xaml code like below.
<Style TargetType="{x:Type local1:CustomButton}" >
<Setter Property="FontSize" Value="27"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Foreground" Value="#1d5560"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local1:CustomButton}">
<Grid>
<Image Stretch="Fill" >
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="Resources/Pfad55.png" />
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local1:CustomButton},Path=ContentOff}"
Value="SETTINGS">
<Setter Property="Source"
Value="Resources/Pfad55-1.png" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<ContentPresenter HorizontalAlignment="Left" Margin="50,0,0,0" Content="{TemplateBinding ContentOff}"
VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And Chnage your MainWindow.xaml implementation with this
<Controls:CustomButton Grid.Row="8" Grid.Column="2" ContentOff="SETTINGS"/>
You were using App.xaml style with BigButtonStyle , that's why custom control styles and trigger was not firing. Your App.xaml style was locally overriding custom control style and trigger from Generic.xaml.

how to base a style on another style and refer to its elements?

i have an ExtendedTreeView control which extendes TreeView. My extendedTreeView has a property called Highlight so unlike a normal TreeView, i want the extendedTreeView to highlight items based on this Highlight property rather than IsSelected. So I have a style defined for a TreeView like below.
<Style x:Key="TreeViewStyle" TargetType="{x:Type TreeViewItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<Border Name="Bd"
Background="Transparent"
//other stuff
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="Bd" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And then i define another style for the extendedTreeView which is based on the TreeViewStyle. The problem is that when i try to set "Bd" which is the border, it can't recognize it and has no idea what im referring to.
<Style x:Key="TreeViewStyle2" TargetType="{x:Type controls:ExtendedTreeView}" BasedOn="{StaticResource TreeViewStyle}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<ControlTemplate.Triggers>
<Trigger Property="controls:ExtendedTreeView.Highlight" Value="true">
<Setter TargetName="Bd" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
IS there anyway of fixing this? or an alternative way of doing it? thanks

Check Toggle button state and manual trigger it using C#

I am trying to trigger ToggleButton programmatically using C#.
I have a ToggleButton the switch imaged between muted and unmuted. If I toggle the button to muted I have the expected image but if I change the VolumeBar I have to trigger the button from C# because if doesn't do it automatically.
<ToggleButton x:Name="MuteBtn" Height="20" Width="20" Background="Transparent" Click="MuteButton_Click">
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="Content">
<Setter.Value>
<Image Source="/Resources/audio-volume_on.ico" />
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Content">
<Setter.Value>
<Image Source="/Resources/volume_off.ico" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
I have a class called VolumeBar_ValueChanged that has to Toggle the button based on the VolumeBar Value.
As #Anu Viswan said, The isChecked property may solve your problem.
Try to use ControlTemplate for ToggleButton.
<ToggleButton>
<ToggleButton.Style>
<Style TargetType="ToggleButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Image x:Name="borderImage" Source="Image1.jpg"/>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Source" Value="Image2.jpg" TargetName="borderImage"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ToggleButton.Style>
</ToggleButton>

WPF Data Trigger

Hi I just wondered if I could get some help, I'm having alot of trouble getting the data trigger to work, if i remove the data trigger and place the drop shadow just as a setter it works. But i want to be able to give the user the option of turning on and off the drop shadow so I thought the data trigger would be the answer.
Basically I want to add the data trigger all over my control styles and just be able to change the fancyGraphics BOOL to TRUE or FALSE and have every controls drop shadow adjust.
Thanks in advance.
Here is my XAML
<sys:Boolean x:Key="fancyGraphics" >True</sys:Boolean>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="#EEE"></Setter>
<Setter Property="Foreground" Value="#555"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderThickness="1" BorderBrush="#DDD">
<Grid>
<ContentPresenter x:Name="MyContentPresenter" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#333"></Setter>
<Setter Property="BorderBrush" Value="#888"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=fancyGraphics}" Value="True">
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect BlurRadius="20"
Opacity="0.5"
ShadowDepth="0"
Color="#111" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
The binding in DataTrigger looks for a property named fancyGraphics. But, fancyGraphics is a static resource. You should define the binding as such:
<DataTrigger Binding="{Binding Source={StaticResource fancyGraphics}}" Value="True">
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect BlurRadius="20"
Opacity="0.5"
ShadowDepth="0"
Color="#111" />
</Setter.Value>
</Setter>
</DataTrigger>

WPF ToggleButton not changing colour when checked

I am trying to make a style for ToggleBox so that it changes colour when clicked, I have successfully given it a dropdown shadow on mouse over but for some reason when I click it instead of going into the checked state it stays stuck on the mouse over state.
It's XAML is:
<!--Primary toggle button style-->
<Style x:Key="PrimaryRoundedToggleButton" TargetType="ToggleButton">
<Setter Property="Margin" Value="5"/>
<Setter Property="Width" Value="180"/>
<Setter Property="Height" Value="30"/>
<Setter Property="Background" Value="#E08827"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontSize" Value="15"/>
<Setter Property="FontWeight" Value="DemiBold"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border CornerRadius="4" Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border CornerRadius="4" Background="{TemplateBinding Background}">
<Border.Effect>
<DropShadowEffect BlurRadius="4" ShadowDepth="3" Direction="300" Opacity="0.5"/>
</Border.Effect>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border CornerRadius="4" Background="#58585a">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
And the event handler is:
private void primaryToggleButton_Checked(object sender, RoutedEventArgs e)
{
primaryToggleButton.Content = "Restarting...";
serviceStatusChangeTimeout = Int32.Parse(ConfigurationManager.AppSettings.Get("serviceStatusChangeTimeout"));
websiteStatusChangeTimeout = Int32.Parse(ConfigurationManager.AppSettings.Get("websiteStatusChangeTimeout"));
MidTier.ServiceRestart(serviceStatusChangeTimeout);
Thread.Sleep(1000);
cacheBuilderStatus.Source = new BitmapImage(new Uri("pack://application:,,,/WpfCustomControlLibrary1;component/Resources/checkbox-complete.png"));
MidTier.CheckLastModified();
MidTier.webSiteRestart();
MidTier.applicationPoolRecycle();
primaryToggleButton.IsChecked = false;
}
I am also trying to have it change the text in the button as well, but I remember finding how to do that in XAML so I will try and dig that up again before I ask that question.
Thank you.
So your button stays in the mouse over state because there is no trigger for when the mouse is not over (<Trigger Property="IsMouseOver" Value="false"><!--reset things--></Trigger>). With you have to have multiple triggers and on and off you may need to look into MultiDataTrigger. This isn't a need at the moment for you, but I see that it may soon be.
How can I provide multiple conditions for data trigger in WPF?
You should do a trigger when the value of IsMouseOver is false.
Also I would suggest you to override the template and do what you need:
<Setter Property="Template">
...
</ControlTemplate>
And mark ControlTemplate.Triggers for your triggers.

Categories