WPF - creating a trigger to use a resource style - c#

I have a dialog with buttons - the buttons text and functionality are dynamic and changing according to the user's needs.
In most cases the button style is the default style, in case the button is an OK button, I would like the button to use a different style.
I've tried to add a trigger that will change the button style according to a Boolean property:
(when IsOKButton=true use the "RedButtonStyle")
<Button.Template>
<ControlTemplate >
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding IsOKButton}" Value="True">
<Setter Property="Style" Value="{StaticResource RedButtonStyle}"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
the RedButtonStyle is a resource style that can be used in diffrent projects for a diffrent buttons type , so the soultion should be in my project and can't be in the resource style itself.
But when using this trigger I get an exception.
"set property system.windows.controls.control.template threw an exception"
Can anyone help me resolve this problem, or suggest an idea to set the style dynamicly?
Thanks

You could put the trigger in the style itself:
<Style x:Key="OKButtonStyle">
<Style.Triggers>
<DataTrigger Binding="{Binding IsOKButton}" Value="True">
//Whatever Property is different in the OKButtonStyle
</DataTrigger>
<DataTrigger Binding="{Binding IsOKButton}" Value="False">
//Set it back to default
</DataTrigger>
</Style.Triggers>
</Style>
Then just give your button the style OKButtonStyle from the start.
If want to make your OK Button mostly the same as a more general style which you want all your buttons to have you can just base it on the general one like this:
<Style x:Key="OKButtonStyle" BasedOn="{StaticResource GeneralButtonStyle}">

Related

WPF control not returning in previous state after triggering

XAML
<utility:InvalidNotification x:Name="InvalidNotificationControl"/>
<Button Content="Clean AppV Cache" Click="Button_Click">
<Button.Style>
<Style TargetType="Button">
<Setter Property="IsEnabled" Value="True"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=InvalidNotificationControl, Path=Visibility}" Value="Visible">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
NOTE
InvalidNotification is a custom UserControl
Now, the DataTrigger works fine initially and disable the button since the Usercontrol is visible.
The problem is when I collapse the Usercontrol based on another condition the button stays disable. I found this related answer which states that The properties changed by triggers are automatically reset to their previous value when the triggered condition is no longer satisfied. which is not my case. Why is that ?
EDIT
Thanks to #mm8 which led me to the solution. So if ever you're trying to bind a control on a UserControl's content (inner TextBlock in my case), just add a second trigger at the bottom of your Usercontrol like so,
<UserControl.Style>
<Style TargetType="UserControl">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=Notification, Path=Visibility}" Value="Visible">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Style>
where notification would be the name of my TextBlock
Your example works provided that you toggle/set the Visibility property of the InvalidNotification control itself, since it is this property that you bind to.
If you set the Visibility property of some element within the InvalidNotification control, you need to bind to this specific element.
You can't do this using an ElementName binding though because the Button and any element defined in the InvalidNotification control don't belong to the same namescope.

Bind Path in ResourceDictionary's dependant on VM property

I've created a ResourceDictionary that defines a bunch of System.Windows.Shapes.Path that are used in the ContentPresenter of a Button ControlTemplate.
I'd like to change one of the Paths out based on a ViewModel property. If true the button uses one path from the ResourceDictionary, if false a different one.
Currently I just reference a StaticResource in the xaml to point directly to the path I want displayed.
What's the best way to do this?
You would have to modify the content template of the button in style by referring to the elements from you resource dictionary.
Something like this:
<Button.Style>
<Style TargetType="Button">
<Setter Property="ContentTemplate" Value="{StaticResource cp2}"></Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource cp1}"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
I have used mouse over property as my trigger to change the content template.
You can use DataTrigger instead of Trigger

Event Trigger for Button in XAML - No Code Behind

Im trying to make an event trigger using a button to tell the ListView each time to resize it columns automatically.
ive used different methods but non of them worked, the event is in this code defined inside the ListView and im trying through DataBinding to take the action (IsPressed) from the Button trigger the ListView.
when i try to execute the code i get the following error
The tag 'Binding' does not exist in XML namespace 'http://schemas.microsoft.com/winfx/2006/xaml/presentation'.
im doing the DataBinding in a wrong way? will this code in this way work at all?
thanks in advance!
<ListView.Style>
<Style>
<Style.Triggers>
<Trigger Binding = "{Binding ElementName=Button1,Path=IsPressed}" Value="True">
<Setter Property="GridViewColumn.Width" Value="Auto"/>
</Trigger>
</Style.Triggers>
</Style>
</ListView.Style>
To bind a Trigger to a property outside the element scope use DataTrigger
Example:
<DataTrigger Binding="{Binding ElementName=Button1, Path=IsPressed}" Value="True">
<Setter Property="GridViewColumn.Width" Value="Auto"/>
</DataTrigger>
A regular trigger(Property Trigger) only responds to dependency properties, which you are trying as of now:
<Style.Triggers>
<Trigger .....
Use DataTrigger, it can be bound to another control
<Style.Triggers>
<DataTrigger Binding="{Binding

Using Style tag effectively in WPF for different images

I use Styles to define what happens when a user hovers over an image like this.
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="c:\\2.bmp"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Source" Value="C:\\1.bmp"/>
</Trigger>
</Style.Triggers>
</Style>
But, I guess for all the images that I include in my application, the same images defined in 'Value' attributes are used. What If I need a different on-hover image for different Images without this custom overriding?
In this case, any ideas what I should use? Or what is the better way to handle hovering of images in WPF?
We should define a x-key value like Jon suggested!
<Style x:Key="Name_of_your_style" TargetType="{x:Type Image}">
<Setter Property="Source" Value="c:\\2.bmp"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Source" Value="C:\\1.bmp"/>
</Trigger>
</Style.Triggers>
and while using this snippet use something like
<Image Style="{StaticResource Name_of_your_style}" Name="I1" />
<Image Name="I2" />
This will make the image I1(defined first) to use the above template(on hover handled) while the other image remains as per your current template.
You can define several different styles and give them an x:Key value, rather than a TargetType value. You can then simply set the Style attribute of your images to the x:Key of the appropriate style.
If you want to apply a single style to the majority of your Images, but you want to override it for just a few of them, then you can combine the two methods. If you assign a style to a type of element (via the TargetType attribute), you can override this on specific elements by explicitly specifying their Style attribute. Also, if you set Style={x:Null}, you can make an element revert to the default style.

Changing a Button's Click event based on a DataTrigger

I'm trying to change a Button's Click property/event when a DataTrigger is triggered but I'm not sure if this is the best method to do it. In fact, it won't even compile :)
What I have looks like this:
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=ObjectTreeView, Path=SelectedItem.Replaceable}" Value="False">
<Setter Property="Content" Value="Add" />
<Setter Property="Button.Click" Value="AddObject_Click" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=ObjectTreeView, Path=SelectedItem.Replaceable}" Value="True">
<Setter Property="Content" Value="Replace" />
<Setter Property="Button.Click" Value="ReplaceObject_Click" />
</DataTrigger>
</Style.Triggers>
</Style>
Compiling gives me an error message saying "Cannot find the Style Property 'Click' on the type 'System.Windows.Controls.Button'"
Any suggestions? If this not possible, what alternatives are there?
Thanks!
Edit:
I thought I found the solution which was to use an EventSetter, but EventSetters aren't supported inside Triggers. What I thought would've worked was:
<EventSetter Event="Button.Click" Handlder="AddObject_Click" />
But like I said, this is supported at all.
Wouldn't it be easier to just have one click event and in that event, an if statement based on your DataTrigger?
Click isn't a property, it's an event. Buttons have a property IsPressed that becomes true when the button is being pressed. You could try using that.
Instead of using a Click event, try using the button's Command property. You should be able to switch which command it points to based on a Trigger.

Categories

Resources