Wpf button data trigger - wpf

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 i want to remove the image from the button and want to update the button with some text.
<StackPanel Grid.Row="3" Orientation="Horizontal" HorizontalAlignment="Right">
<Button ToolTip="Attach Approval"
Height="25"
Command="{Binding AddAttachmentCommand}"
Margin="5,10,5,10">
<StackPanel Orientation="Horizontal">
<Image Source="/UILibrary;component/Themes/Default/Images/Attach.PNG"/>
</StackPanel>
<Button.Style>
<Style TargetType="{x:Type Button}">
<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>
</Button>
<StackPanel Orientation="Horizontal"
Height="25"
Margin="5,10,5,10"
Visibility="{Binding IsAttachmentAvailable, Converter={StaticResource BooleanToVisibilityConverter}}">
<TextBlock Margin="3">
<Hyperlink Command="{Binding OpenAttachmentCommand}">
<TextBlock Text="{Binding Attachment.FileName}"/>
</Hyperlink>
</TextBlock>
<customControls:CloseButton Width="15" Height="15" Command="{Binding RemoveAttachmentCommand}">
<customControls:CloseButton>
Remove attachment
</customControls:CloseButton>
</customControls:CloseButton>
</StackPanel>
<Button Height="25"
Width="80"
Margin="5,10,5,10"
Content="Approve"
Command="{Binding ApproveTemplateCommand}"/>
<Button Height="25"
Width="80"
Margin="5,10,5,10"
Content="Preview"
Command="{Binding PreviewTemplateCommand}"/>
<Button Content="Save"
Command="{Binding SaveTemplateCommand}"
Height="25"
Width="80"
Margin="5,10,5,10"/>
<Button Height="25"
Width="80"
Margin="5,10,10,10"
Content="Cancel"
Command="{Binding CancelCommand}"/>
</StackPanel>

If Button.Content is set in the <Button> tag itself like you have, it will take precedence over any styled values.
You need to move your StackPanel out of the <Button.Content> tag directly, and put it in the style or another data trigger instead.
<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>
See MSDN's Dependency Property Precedence List for more information.

Related

Change Visibility of Stack Panel inside List view on Mouse Hover

Below is my list view
<ListView Grid.Column="0" Grid.Row="2" BorderThickness="0" ItemTemplate="{StaticResource ListViewDataTemplate}" x:Name="NewTasks"
SelectedItem="{Binding SelectedTask}"/>
Data Template For my list view
<DataTemplate x:Key="ListViewDataTemplate">
<StackPanel Style="{StaticResource ListViewStackPanel}">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Name="UserActions">
<Image Source="\Images\Edit.png" Height="30" Width="30" cal:Message.Attach="[Event MouseUp] = [Action EditTask]"/>
<Image Source="\Images\Delete.png" Height="15" Width="15" cal:Message.Attach="[Event MouseUp] = [Action DeleteTask]"/>
</StackPanel>
<TextBlock Text="{Binding Name}" Margin="5" FontSize="20" FontWeight="SemiBold"/>
<TextBlock Text="{Binding Description}" Margin="5" TextWrapping="Wrap"/>
</StackPanel>
</DataTemplate>
Trigger for my stack panel in list view
<Style TargetType="StackPanel" x:Key="ListViewStackPanel">
<Style.Triggers>
<DataTrigger Binding="{Binding Priority}" Value="Low">
<Setter Property="Background" Value="#cccedb" />
<Setter Property="TextBlock.Foreground" Value="#083045"/>
</DataTrigger>
<DataTrigger Binding="{Binding Priority}" Value="Medium">
<Setter Property="Background" Value="#fbbf79" />
<Setter Property="TextBlock.Foreground" Value="#373c3e"/>
</DataTrigger>
<DataTrigger Binding="{Binding Priority}" Value="High">
<Setter Property="Background" Value="#cd5849" />
<Setter Property="TextBlock.Foreground" Value="White"/>
</DataTrigger>
</Style.Triggers>
</Style>
When mouse is hovered on an item in list view the i want to show user actions for that item.
Addd Trigger to your DataTemplate to achieve your requirements.
<DataTemplate x:Key="ListViewDataTemplate">
<StackPanel Style="{StaticResource ListViewStackPanel}">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Name="UserActions" Visibility="Collapsed">
<Image Source="\Images\Edit.png" Height="30" Width="30" cal:Message.Attach="[Event MouseUp] = [Action EditTask]"/>
<Image Source="\Images\Delete.png" Height="15" Width="15" cal:Message.Attach="[Event MouseUp] = [Action DeleteTask]"/>
</StackPanel>
<TextBlock Text="{Binding Name}" Margin="5" FontSize="20" FontWeight="SemiBold"/>
<TextBlock Text="{Binding Description}" Margin="5" TextWrapping="Wrap"/>
</StackPanel>
<DataTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="UserActions" Property="Visibility" Value="Visible" />
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
My Code
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow" Height="600" Width="600">
<Window.Resources>
<Style TargetType="StackPanel" x:Key="ListViewStackPanel">
<Style.Triggers>
<DataTrigger Binding="{Binding Priority}" Value="Low">
<Setter Property="Background" Value="#cccedb" />
<Setter Property="TextBlock.Foreground" Value="#083045"/>
</DataTrigger>
<DataTrigger Binding="{Binding Priority}" Value="Medium">
<Setter Property="Background" Value="#fbbf79" />
<Setter Property="TextBlock.Foreground" Value="#373c3e"/>
</DataTrigger>
<DataTrigger Binding="{Binding Priority}" Value="High">
<Setter Property="Background" Value="#cd5849" />
<Setter Property="TextBlock.Foreground" Value="White"/>
</DataTrigger>
</Style.Triggers>
</Style>
<DataTemplate x:Key="ListViewDataTemplate">
<StackPanel Style="{StaticResource ListViewStackPanel}">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Name="UserActions" Visibility="Collapsed">
<Image Source="\Images\Edit.png" Height="30" Width="30" />
<Image Source="\Images\Delete.png" Height="15" Width="15" />
</StackPanel>
<TextBlock Text="{Binding Name}" Margin="5" FontSize="20" FontWeight="SemiBold"/>
<TextBlock Text="{Binding Description}" Margin="5" TextWrapping="Wrap"/>
</StackPanel>
<DataTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="UserActions" Property="Visibility" Value="Visible" />
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</Window.Resources>
<ListView Grid.Column="0" Grid.Row="2" BorderThickness="0" ItemTemplate="{StaticResource ListViewDataTemplate}" x:Name="NewTasks"
SelectedItem="{Binding SelectedTask}"/>
</Window>

Using DataTrigger for TextBlock HorizontalAlignment property

On my Grid I Have TextBlock and Button.
If Button is not visible I want my TextBlock.HorizontalAlignment to be set to Center.
If Button is visible I want my TextBlock.HorizontalAlignment to be set to Right. Here is my code:
<TextBlock Grid.Row="0" VerticalAlignment="Center" Name="myTextBlock" Text="{Binding TileTextId}" TextWrapping="Wrap" TextAlignment="Center" >
<TextBlock.Triggers>
<DataTrigger Binding="{Binding ElementName=myButton, Path=IsVisible}" Value="True">
<Setter Property="HorizontalAlignment" Value="Right" />
</DataTrigger>
</TextBlock.Triggers>
</TextBlock>
I get the error:
'HorizontalAlignment' member is not valid because it does not have a qualifying type name.
So I tried to add TextBlock.HorizontalAlignment, like this:
<TextBlock Grid.Row="0" VerticalAlignment="Center" Name="myTextBlock" Text="{Binding TileTextId}" TextWrapping="Wrap" TextAlignment="Center" >
<TextBlock.Triggers>
<DataTrigger Binding="{Binding ElementName=myButton, Path=IsVisible}" Value="True">
<Setter Property="TextBlock.HorizontalAlignment" Value="Right" />
</DataTrigger>
</TextBlock.Triggers>
</TextBlock>
I get the error:
XamlParseException
How should I do that?
Don't try to use TextBlock.Triggers, instead go for a Style with Style.Triggers.
<StackPanel>
<TextBlock Text="TextBlock Content" Margin="5">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=myButton,Path=IsVisible}" Value="True">
<Setter Property="HorizontalAlignment" Value="Right"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<Button x:Name="myButton" Content="Click Me!" Margin="5"/>
</StackPanel>
Take note of the documentation, as it mentions, why style triggers are needed here.
Note that the collection of triggers established on an element only
supports EventTrigger, not property triggers (Trigger). If you require
property triggers, you must place these within a style or template and
then assign that style or template to the element either directly
through the Style property, or indirectly through an implicit style
reference.
Try to do this with Style
<TextBlock Grid.Row="0" VerticalAlignment="Center" Name="myTextBlock" Text="{Binding TileTextId}" TextWrapping="Wrap" TextAlignment="Center" >
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=myButton, Path=IsVisible}" Value="True">
<Setter Property="HorizontalAlignment" Value="Right" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>

Image inside a GridControl -Devexpress

I have a grid control in which the first column and cell shows a trash icon. But the trash icon should be visible only when its row is selected.
I have a style:
<Style TargetType="{x:Type Image}" x:Key="ImageStatusStyle">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=RowData.IsFocused, UpdateSourceTrigger=PropertyChanged}" Value="true">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
and a data template:
<DataTemplate x:Key="TrashIconCellTemplate" >
<Button Height="15" Width="15" Command="{Binding ElementName=GroupCodeListView,Path=DataContext.MarkRowForDeletionCommand}">
<Button.Template>
<ControlTemplate>
<Image Source="../Resources/crane.png" Style="{StaticResource ImageStatusStyle}" Visibility="Hidden"/>
</ControlTemplate>
</Button.Template>
</Button>
</DataTemplate>
A grid control:
<dxg:GridControl ItemsSource="{Binding GroupCodes, Mode=TwoWay}"
SelectedItems="{Binding
SelectedGroupCodes,Mode=TwoWay}"
SelectionMode="Row"
x:Name="Grid"
ClipboardCopyMode="ExcludeHeader"
Margin="0,0,0,0"
Height="360"
MinWidth="400"
CustomRowFilter="FilterDeleted">
and the grid cell column referencing the above:
<dxg:GridColumn FieldName="IconUnbound"
UnboundType="Object"
CellTemplate="{StaticResource TrashIconCellTemplate}"
CellStyle="{StaticResource GroupCodeColorStyle}" />
The trash image in the first cell should appear when the row is selected only.
The image remains in the default state of hidden. The data trigger is not working. What am I doing wrong here?
If you want to check whether the row is selected then you need to use RowData.IsSelected property. Also, you must set the Visibility in your Style section, not in the Image itself.
Here is example:
0. Style:
<Style TargetType="{x:Type Image}" x:Key="ImageStatusStyle">
<Setter Property="Visibility" Value="Hidden" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=RowData.IsSelected, UpdateSourceTrigger=PropertyChanged}" Value="true">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
1. Image:
<Image Source="../Resources/crane.png" Style="{StaticResource ImageStatusStyle}" />

TargetName not recognized

I am trying to enable and disable a Button based on selection in a ListBox. If a value is selected the button should be enabled.
I am trying to use triggers but it is giving me an error
'targetname not recognized'.
<UserControl x:Class="Qualification.View.QualificationView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
Height="500" Width="500">
<Grid>
<Button Name="btnOpen" Command="Open" CommandParameter="{Binding ElementName=lstName, Path=SelectedValue}" Height="23" Width="100" Margin="259,325,141,152">Add Qualification</Button>
<Grid.CommandBindings x:Uid="key">
<CommandBinding Command="Open" CanExecute="CommandBinding_CanExecute" Executed="CommandBinding_Executed"/>
</Grid.CommandBindings>
<Grid.Resources>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
<DataTemplate x:Key="eble">
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=IsSelected,RelativeSource={RelativeSource TemplatedParent}}" Value="True">
<Setter TargetName="btnOpen" Property="IsEnabled" Value="False"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Grid.Resources>
<Label Height="23" Width="100" Margin="17,35,383,442" RenderTransformOrigin="0.48,-3.217">Search</Label>
<TextBox Name="txtSearch" Text="{Binding Qm.Search, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" Height="23" Width="122" Margin="103,37,0,440" HorizontalAlignment="Left"></TextBox>
<Button Name="btnGo" Height="22" Width="30" Margin="205,37,265,441" RenderTransformOrigin="0.633,-1.318" Click="Button_Click_1">Go</Button>
<ListBox Name="lstName" ItemsSource="{Binding DocList}" Width="218" Margin="17,82,265,152">
</ListBox>
<!--<Button Command="{Binding AddQual}" CommandParameter="{Binding ElementName=lstName, Path=SelectedValue}" Height="23" Width="100" Margin="259,325,141,152">Add Qualification</Button>-->
</Grid>
</UserControl>
You could create a style for your button which handles this.
<Style x:Key="EnableButtonStyle" TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=SelectedItem, ElementName=yourListBox}" Value="{x:Null}">
<Setter Property="IsEnabled" Value="False"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
Then you bind it to your button:
<Button Style="{DynamicResource ResourceKey=EnableButtonStyle}"/>

What's wrong with this ContentTemplate?

I'm getting an error for this content template within a style: "Must specify both Property and Value for Setter." Aren't I doing that?
<Style x:Key="LinkButton" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<ContentPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Label x:Name="ContentRoot">
<StackPanel Orientation="Horizontal">
<Viewbox Width="24" Height="24" VerticalAlignment="Center">
<Image x:Name="ButtonImage" Source="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Button}}, Path=Tag}" />
</Viewbox>
<TextBlock VerticalAlignment="Center" x:Name="ButtonText" Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Button}}, Path=Content}"></TextBlock>
</StackPanel>
</Label>
<DataTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="ButtonText" Property="TextBlock.TextDecorations" Value="Underline"/>
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</Setter.Value>
</Setter>
And here is a button that will be using this style:
<Button Name="HelpButton" Style="{StaticResource LinkButton}" Height="30" Content="Help" Tag="Help.png"/>
Thanks!
I have loaded this up and have no such problems. The only problem I see is that your button will never have the style applied. This is because if you want the style applied you need to remove the x:Key from the style. Otherwise if you want the style applied only to the HelpButton, the definition should look like this:
<Button Name="HelpButton" Style="{StaticResource LinkButton}" Height="30" Content="Help" Tag="Help.png"/>
But I cannot see the error you are seeing.

Resources