Search code examples
wpfxamldatatrigger

How to change Icon of button with data trigger ? wpf


I am new to wpf. Actully i want to change button icon(play.ico/stop.ico). when i click the button it changes status(status is database column) value 'Online' to Offline, or Offline to Online. It updating in database also but I want to show when status is online buttton should show stop.ico and when I status is offline button should show play.ico. How to achieve this? I tried with below code but its not working. please help and suggest what i am missing something.

//Xaml code

<StackPanel Margin="0 0 0 0" Grid.Column="5"  Grid.Row="0" Grid.RowSpan="2">
                    <Button Name="Ignition_Button1" Click="Ignition_Button1_Click_1" Width="35" Height="35" Margin="16,5,16,0"

                            Style="{DynamicResource CircleButton}"
                            Command="{Binding StartStopCommand}">
                        <Button.ToolTip>
                            <ToolTip>
                                <StackPanel>
                                    <TextBlock FontWeight="Bold"
                                               Text="Start or Stop Control Center" />
                                </StackPanel>
                            </ToolTip>
                        </Button.ToolTip>
                        <StackPanel Orientation="Vertical">
                            <Rectangle Width="15" Height="15" StrokeThickness="0">
                                <Rectangle.Style>
                                    <Style TargetType="{x:Type Rectangle}">
                                        <Setter Property="Fill" Value="{StaticResource play.ico}" />
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding Status, UpdateSourceTrigger=PropertyChanged}" Value="Online">
                                                <Setter Property="Fill" Value="{StaticResource stop.ico }" />
                                            </DataTrigger>
                                            <DataTrigger Binding="{Binding Status, UpdateSourceTrigger=PropertyChanged}" Value="Offline">
                                                <Setter Property="Fill" Value="{StaticResource play.ico}" />
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </Rectangle.Style>
                            </Rectangle>
                        </StackPanel>
                    </Button>
                </StackPanel>

Solution

  • Several things I would suggest here. Rather than ico which are bitmap and will have jaggies, I would recommend geometries and paths. With a button which has two states you toggle between then a togglebutton is a good candidate. Below I put my two geometries in resources of my togglebutton. These are more usually put into a resource dictionary (along with the many other geometries used for iconography) and merged in app.xaml.

            <ToggleButton IsChecked="True"
                          IsThreeState="False"
                          >
                <ToggleButton.Resources>
                    <Geometry x:Key="StopGeom">
                        M0,0L32,0 32,32 0,32z
                    </Geometry>
                    <Geometry x:Key="PlayGeom">
                        M0,0L16,8 32,16 16,24 0,32 0,16z
                    </Geometry>
                </ToggleButton.Resources>
                <Path Fill="Black"
                      Stretch="Uniform"
                      Margin="4">
                    <Path.Style>
                        <Style TargetType="Path">
                            <Setter Property="Data" Value="{StaticResource PlayGeom}"/>
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding IsChecked, RelativeSource={RelativeSource AncestorType={x:Type ToggleButton}}}" Value="True">
                                    <Setter Property="Data" Value="{StaticResource StopGeom}"/>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </Path.Style>
                </Path>
            </ToggleButton>
    

    This needs more work but should give you the idea of one way to do this. For more about layout and geometries:

    https://social.technet.microsoft.com/wiki/contents/articles/32610.wpf-layout-lab.aspx

    I don't know how you're styling the shape of your button, but I use this one to emphasise to wpf newbies what lookless controls means:

    https://social.technet.microsoft.com/wiki/contents/articles/29866.aspx