Calling a Image style - c#

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}">

Related

WPF: Changing button background and font is not working

I have a list of button in a StackPanel. Those buttons allow me to switch between different usercontrols. When one button is pressed, I want the button style to change so that the user can know which button is active. To achieve this, I have implemented a style trigger that switches the background color as well as the text font on click or on MouseOver. Here is the code:
<Button Uid="0" Width="120" Content="Manage" Height="50" Background="{x:Null}"
BorderBrush="{x:Null}" FontWeight="DemiBold" Click="Button_Click">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True"/>
<Condition Property="IsFocused" Value="True"/>
<Condition Property="IsPressed" Value="True"/>
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Background" Value="LightBlue"/>
<Setter Property="BorderBrush" Value="DarkBlue"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="TextBlock.FontWeight" Value="Bold"/>
</MultiTrigger.Setters>
</MultiTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<Button Uid="1" Width="120" Content="Settings" Height="50" Background="{x:Null}"
BorderBrush="{x:Null}" FontWeight="DemiBold" Click="Button_Click"/>
However, this code does not work and I can't figure out why.
I have seen multiple questions with the same problem and it seems like I am doing it right but somehow, when I run the app, the styling does not work. Any clue as of why?
It will be much simpler if you will using RadioButton and apply style from ToggleButton. Then you can use the property IsChecked to style your button.
Please look at my example:
<StackPanel>
<StackPanel.Resources>
<Style x:Key="MenuButtonStyle" TargetType="RadioButton" BasedOn="{StaticResource {x:Type ToggleButton}}">
<Setter Property="Background" Value="{x:Null}"/>
<Setter Property="BorderBrush" Value="{x:Null}"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="TextBlock.FontWeight" Value="DemiBold"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsChecked, RelativeSource={RelativeSource Self}}" Value="True">
<Setter Property="Background" Value="LightBlue"/>
<Setter Property="BorderBrush" Value="DarkBlue"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="TextBlock.FontWeight" Value="Bold"/>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Resources>
<RadioButton Uid="0" Width="120" Content="Manage" Height="50" Style="{StaticResource MenuButtonStyle}"/>
<RadioButton Uid="1" Width="120" Content="Settings" Height="50" Style="{StaticResource MenuButtonStyle}" />
</StackPanel>

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>

How to add parameters to an existing style

I have the following button in my XAML:
<Button Content="ADD"
Style="{DynamicResource MaterialDesignFlatButton}" />
I would like to keep the style and create a validation rule for it, like if some textbox is empty it should disable the button and set a tooltip on it.
So I tried this:
<Button Content="ADD"
Command="{Binding AddDateCommand}"
VerticalAlignment="Top"
Margin="8 0 0 0">
<Button.Style>
<Style BasedOn="{StaticResource MaterialDesignFlatButton}">
<triggers to check the rules and set the attributes/>
</Style>
</Button.Style>
</Button>
But I'm getting the following error:
Can only base on a Style with target type that is base type
'IFrameworkInputElement'
You will get an error : Style can be set only once in your present code.
You have to use TargetType with BasedOn styles.
So, define your style should be conceptually like this :
<Style x:Key="MaterialDesignFlatButton" TargetType="Button">
<Setter Property="Background" Value="Red"/>
</Style>
<Style x:Key="NewStyle" BasedOn="{StaticResource MaterialDesignFlatButton}"
TargetType="Button">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=tb, Path=Text.Length, Mode=OneWay}" Value="10"/>
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="True"/>
</MultiDataTrigger>
</Style.Triggers>
<Setter Property="BorderBrush" Value="Cornsilk"/>
<Setter Property="BorderThickness" Value="15"/>
<Setter Property="Foreground" Value="MediumPurple"/>
<Setter Property="FontSize" Value="15"/>
</Style>
use IsEnabled property of the button if you have one TextBox:
<Button Content="ADD"
Command="{Binding AddDateCommand}"
VerticalAlignment="Top"
Margin="8 0 0 0"
IsEnabled="{Binding ElementName=yourTxtBox, Path=Text.Length, Mode=OneWay}" />
But for two TextBoxes you should use:
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=firstTxtBox, Path=Text.Length, Mode=OneWay}" Value="0"/>
<Condition Binding="{Binding ElementName=lastTxtBox, Path=Text.Length, Mode=OneWay}" Value="0"/>
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="False"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Button.Style>

wpf button command binding after trigger the propery changes

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>

How to set TabIndex in Hyperlink?

I am new to WPF, I dont know how to do this.
I tried following code -
<TextBlock Grid.Column="3" Grid.Row="3" Visibility="{Binding Path=CanCreate, Converter={StaticResource BoolVisibilityConverter}}">
<Hyperlink KeyboardNavigation.TabIndex="2" Command="{Binding Path=CreateCommand}">Create
<Hyperlink.Style>
<Style TargetType="{x:Type Hyperlink}">
<Setter Property="KeyboardNavigation.IsTabStop" Value="False" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=CanCreate, Converter={StaticResource BoolVisibilityConverter}}">
<Setter Property="KeyboardNavigation.IsTabStop" Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
</Hyperlink.Style>
</Hyperlink>
</TextBlock>
Visibility depends on CanCreate Dependency property. Here IsTabStop is not enabling. Can anyone suggest the solution. Thanks in advance.
Requirement
I want to set TabIndex to hyperlink when it is visible.
You don't need a converter in the DataTrigger change your Hyperlink.Style to:
<Hyperlink.Style>
<Style TargetType="{x:Type Hyperlink}">
<Setter Property="KeyboardNavigation.IsTabStop" Value="False" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=CanCreate}" Value="True">
<Setter Property="KeyboardNavigation.IsTabStop" Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
</Hyperlink.Style>
EDIT: You may also want to remove focus when your TextBlock and Hyperlink is invisible, you can do it by adding another DataTrigger:
<Hyperlink.Style>
<Style TargetType="{x:Type Hyperlink}">
<Setter Property="KeyboardNavigation.IsTabStop" Value="False" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=CanCreate}" Value="True">
<Setter Property="KeyboardNavigation.IsTabStop" Value="True" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=CanCreate}" Value="False">
<Setter Property="Focusable" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</Hyperlink.Style>

Categories