wpf button command binding after trigger the propery changes - c#

i have a button in my wpf form and the button is having the image text in mvvm application when i click the button it will attach the file, my requirement is when it attached successfully the text is changed to Approve , I want to write another command propery for this command after changed the text to Approve.
<Button ToolTip="Attach Approval"
Height="25"
Command="{Binding AddAttachmentCommand}"
Margin="5,10,5,10">
<Button.Style>
<Style TargetType="{x:Type Button}">
<!-- Default Content value -->
<Setter Property="Content">
<Setter.Value>
<StackPanel Orientation="Horizontal">
<Image Source="/UILibrary;component/Themes/Default/Images/Attach.PNG"/>
</StackPanel>
</Setter.Value>
</Setter>
<!-- Triggered values -->
<Style.Triggers>
<DataTrigger Binding="{Binding IsAttachmentAvailable}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
<Setter Property="Content" Value="Appprove"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsAttachmentAvailable}" Value="False">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>

If you want to change a property (in your case the Command) in a trigger, you have to initialise the property in the style setter. To make your code work remove the command property from the button and add the command property to the style setter.
<Button ToolTip="Attach Approval"
Height="25"
Margin="5,10,5,10">
<Button.Style>
<Style TargetType="{x:Type Button}">
<!-- Default Content value -->
<Setter Property="Command" Value="{Binding AddAttachmentCommand}"/>
<Setter Property="Content">
<Setter.Value>
<StackPanel Orientation="Horizontal">
<Image Source="/UILibrary;component/Themes/Default/Images/Attach.PNG"/>
</StackPanel>
</Setter.Value>
</Setter>
<!-- Triggered values -->
<Style.Triggers>
<DataTrigger Binding="{Binding IsAttachmentAvailable}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
<Setter Property="Content" Value="Appprove"/>
<Setter Property="Command" Value="SOME OTHER COMMAND"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsAttachmentAvailable}" Value="False">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>

Related

Enabling TextBox with trigger

I want a Textbox to be disabled, except the user hovers with the mouse over it. But this does not seam to work, the Textbox is still not editable if I hover over it. (Yes I know that this is unusual.)
What I tried is:
<Border>
<TextBox Text="Hover to edit me!" IsEnabled="False" >
<TextBox.Style>
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Border}, Path=IsMouseOver}" Value="True">
<Setter Property="IsEnabled" Value="True" />
</DataTrigger>
<!-- this does not work either -->
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsMouseOver}" Value="True">
<Setter Property="IsEnabled" Value="True" />
</DataTrigger>
<!-- neither did this -->
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="IsEnabled" Value="True" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</Border>
I wonder if it is possible at all using a trigger?
This is because of the Dependency Property Value Precedence in WPF.
You need to set the IsEnabled property to false in the Style, so the trigger can override the value.
The local value has always a higher priority, so setting IsEnabled="False" directly in the text box will override any style or style trigger value.
Here is a working example:
<Border>
<TextBox Text="Text">
<TextBox.Style>
<Style TargetType="TextBox">
<Setter Property="IsEnabled" Value="False"/>
<Style.Triggers>
<DataTrigger
Binding="{Binding IsMouseOver,
RelativeSource={RelativeSource FindAncestor, AncestorType=Border}}"
Value="True">
<Setter Property="IsEnabled" Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</Border>

WPF - Hide/Show Image Based on Expander IsExpanded

I would like to show an image if the expander is collapsed and hide it when it's expanded. I tried the following but it doesn't work. Is there a way to do so without using a converter?
<Image x:Name="fgImage" Source="Resources/Images/MissingImage.png" Margin="0,96,258,-75" Height="110" VerticalAlignment="Top" HorizontalAlignment="Right" Width="110">
<Image.Style>
<Style TargetType="Image">
<Setter Property="Visibility" Value="Visible"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=orderDetailsExpander, Path=IsExpanded}">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
your DataTrigger must be like that
<DataTrigger Binding="{Binding ElementName=orderDetailsExpander, Path=IsExpanded}" Value="True">
all the Image property
<Image x:Name="fgImage" Source="Resources/Images/MissingImage.png" Margin="0,96,258,-75" Height="110" VerticalAlignment="Top" HorizontalAlignment="Right" Width="110">
<Image.Style>
<Style TargetType="Image">
<Setter Property="Visibility" Value="Visible"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=orderDetailsExpander, Path=IsExpanded}" Value="True">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
You DataTrigger needs a value, for example
Value="True"
According to the documentation, the default value is null

Why sometimes WPF DataTrigger not work?

The control is a button and if I set the properties : Content and Background in design ,then the DataTrigger won't work at all(DataTrigger is to set the content and background properties)
And if I remove the properties value I set in the design,when I run the program and change the state property that will fire the trigger,the datatrigger works fine.
How could that be?
Here is my Xaml:
<Style x:Key="DealBTN" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
..........
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding state, Converter={StaticResource Enum2string}}" Value="accepted">
<Setter Property="Background" Value="#BDC3C7"></Setter>
<Setter Property="Content" Value="Dealed"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding state, Converter={StaticResource Enum2string}}" Value="rejected">
<Setter Property="Background" Value="#C0392B"></Setter>
<Setter Property="Content" Value="Canceled"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
<Button Style="{StaticResource DealBTN}" DataContext="{Binding}" Content="Deal" Background="#FF1ABC9C" />
(the state property has INotifyPropertyChanged interface)

Datatrigger on empty string

How can a DataTrigger change the visibility of stackpanel, based on a binded string?
I have the following Xaml
<StackPanel HorizontalAlignment="Right"
Orientation="Horizontal"
Grid.Column="1"
Background="#FF7a7a7a">
<StackPanel.Style>
<Style TargetType="{x:Type StackPanel}">
<Style.Triggers>
<DataTrigger Binding="{Binding SearchText}" Value="">
<Setter Property="Visibility" Value="Hidden"/>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
Content....
</StackPanel>
I Know that SearchText gets updates and binds properly outside the StackPanel
Could somebody point me in the right direction?
This:
<DataTrigger Binding="{Binding SearchText}" Value="">
<Setter Property="Visibility" Value="Hidden"/>
</DataTrigger>
will work for empty string (""), however it will not work for null.
Add another DataTrigger for the null case:
<DataTrigger Binding="{Binding SearchText}" Value="{x:Null}">
<Setter Property="Visibility" Value="Hidden"/>
</DataTrigger>
Correct using String.Empty in XAML:
xmlns:sys="clr-namespace:System;assembly=mscorlib"
...
<DataTrigger Binding="{Binding SearchText}" Value="{x:Static sys:String.Empty}">
Weird as it might sound, the code below works for me:
<StackPanel Background="#FF7a7a7a">
<StackPanel.Style>
<Style TargetType="{x:Type StackPanel}">
<Style.Triggers>
<DataTrigger Binding="{Binding Text, ElementName=textBlock}" Value="">
<Setter Property="Visibility" Value="Hidden"/>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<TextBox x:Name="textBlock" Text="" Width="100" Height="30"></TextBox>
</StackPanel>
Can you tell the value your Property is sending?
Try this
<StackPanel.Style>
<Style TargetType="StackPanel">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding YourBoundPropertyName}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>

Calling a Image style

Is there any way to create a call'able image style? I have multiple buttons on a user control that have the same button and button image style. I can set the button style so that it can be called from the style (dynamic resource) of the button.
Here is an example of my code and the image style code:
<Grid.Resources>
<Style TargetType="Button"
x:Key="ButtonEditSaveStyle">
<Setter Property="IsEnabled"
Value="False" />
<Style.Triggers>
<DataTrigger Binding="{Binding CanEdit}"
Value="True">
<Setter Property="IsEnabled"
Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<Button Width="32"
Height="22"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Name="gdEmployeeInfo_btnUpdateRecord"
Click="gdEmployeeInfo_btnUpdateRecord_Click"
Style="{DynamicResource ResourceKey=ButtonEditSaveStyle}"/>
I want to set my code up so that I can have the call above an have an additional call or a combined call to set the image style as well. I know I can have the image style in the button (as shown in this next code), but I want to have one place to update multiple buttons using the same style setup. Image style code:
<Image>
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source"
Value="edit_32.png" />
<Setter Property="Stretch"
Value="Uniform" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsEditing}"
Value="True">
<Setter Property="Source"
Value="save_smallest.png" />
<Setter Property="Stretch"
Value="Uniform" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
Figured out the answer to my question. This set of code allows me to use dual style setting while creating only one call for the button's style:
<!--SaveEditImageSwitch-->
<Image x:Key="SaveEditImage" x:Shared="False">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source"
Value="edit_32.png" />
<Setter Property="Stretch"
Value="Uniform" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsEditing}"
Value="True">
<Setter Property="Source"
Value="save_smallest.png" />
<Setter Property="Stretch"
Value="Uniform" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<!--ButtonEditSaveStyle-->
<Style TargetType="Button"
x:Key="ButtonEditSaveStyle">
<Setter Property="IsEnabled"
Value="False" />
<Setter Property="Content"
Value="{DynamicResource ResourceKey=SaveEditImage}" />
<Style.Triggers>
<DataTrigger Binding="{Binding CanEdit}"
Value="True">
<Setter Property="IsEnabled"
Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
<Button Width="32"
Height="22"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Name="gdEmployeeInfo_btnUpdateRecord"
Click="gdEmployeeInfo_btnUpdateRecord_Click"
Style="{DynamicResource ResourceKey=ButtonEditSaveStyle}">

Categories