WPF toolbar - why one button is showing ToolTip but not the other? - wpf

In my WPF app, the following XAML in Toolbar is showing ToolTip for Paste button but not for the Copy button. Question: Why it may be happening and how can we resolve it?
<Window x:Class="myWPFApp.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"
xmlns:local="clr-namespace:WpfMkTxTest"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="1140.038">
<Grid>
<!-- Set the styles for the tool bar. -->
<Grid.Resources>
<Style TargetType="{x:Type Button}" x:Key="formatTextStyle">
<Setter Property="FontFamily" Value="Palatino Linotype"></Setter>
<Setter Property="Width" Value="30"></Setter>
<Setter Property="FontSize" Value ="14"></Setter>
<Setter Property="CommandTarget" Value="{Binding ElementName=mainRTB}"></Setter>
</Style>
<Style TargetType="{x:Type Button}" x:Key="formatImageStyle">
<Setter Property="Width" Value="30"></Setter>
<Setter Property="CommandTarget" Value="{Binding ElementName=mainRTB}"></Setter>
</Style>
<Style TargetType="{x:Type RichTextBox}">
<Setter Property="FontFamily" Value="calibri (body)" />
<Setter Property="FontSize" Value="11" />
</Style>
<Style TargetType="{x:Type Paragraph}">
<Setter Property="Margin" Value="0" />
</Style>
</Grid.Resources>
<DockPanel Name="mainPanel">
<!-- This tool bar contains all the editing buttons. -->
<ToolBar Name="mainToolBar" Height="30" DockPanel.Dock="Top">
....
<Button Style="{StaticResource formatImageStyle}" Command="ApplicationCommands.Copy" ToolTip="Copy">
<Image Source="Images\editcopy.png"></Image>
</Button>
<Button Style="{StaticResource formatImageStyle}" Command="ApplicationCommands.Paste" ToolTip="Paste">
<Image Source="Images\editpaste.png"></Image>
</Button>
....
</DockPanel>
</Grid>
</Window>

To show tooltip for command binding buttons, set ToolTipService.ShowOnDisabled = "True"
<DockPanel Name="mainPanel" VerticalAlignment="Top">
<ToolBar Name="mainToolBar" Height="30" DockPanel.Dock="Top">
<Button Style="{StaticResource formatImageStyle}" Command="ApplicationCommands.Copy" ToolTip="Copy" ToolTipService.ShowOnDisabled="True">
<Image Source="C:\Users\mcpl\Documents\Visual Studio 2015\Projects\TestApplication\TestApplication\Images\Add.png"></Image>
</Button>
<Button Style="{StaticResource formatImageStyle}" Command="ApplicationCommands.Paste" ToolTip="Paste" ToolTipService.ShowOnDisabled="True">
<Image Source="C:\Users\mcpl\Documents\Visual Studio 2015\Projects\TestApplication\TestApplication\Images\edit.png"></Image>
</Button>
</ToolBar>

Try using CommandBinding
<ToolBar Name="mainToolBar" Height="30" DockPanel.Dock="Top">
<Button Style="{StaticResource formatImageStyle}" ToolTip="Copy">
<Button.CommandBindings>
<CommandBinding Command="ApplicationCommands.Copy" />
</Button.CommandBindings>
<Image Source="C:\Users\heruvath\Desktop\user-48.png"></Image>
</Button>
<Button Style="{StaticResource formatImageStyle}" ToolTip="Paste">
<Button.CommandBindings>
<CommandBinding Command="ApplicationCommands.Paste" />
</Button.CommandBindings>
<Image Source="C:\Users\heruvath\Desktop\user-48.png"></Image>
</Button>
</ToolBar>

Related

Center a vertically oriented grid in wpf

I started doing the UI for an app in WinForm but I just read about WPF and I decided to re-do my work on it. But since is a new think I ran in a small problem:
As you can see in the screenshot bellow I have 3 vertical buttons that are centered on the main form. How can I achieve the same thing in WPF? I've tried any value I could find to change position but all of them failed.
Here is my main form XAML:
<Window x:Class="YouTubeMusicPlayerWpf.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"
xmlns:local="clr-namespace:YouTubeMusicPlayerWpf"
xmlns:fa="http://schemas.fontawesome.io/icons/"
mc:Ignorable="d" Height="500" Width="900" Background="Black" WindowStyle="None" AllowsTransparency="true" WindowStartupLocation="CenterScreen" Name="mainWindow">
<WindowChrome.WindowChrome>
<WindowChrome ResizeBorderThickness="6" CornerRadius="0" GlassFrameThickness="0">
</WindowChrome>
</WindowChrome.WindowChrome>
<StackPanel Background="#FF201E2B">
<!-- TitleBar buttons -->
<Grid HorizontalAlignment="Right">
<StackPanel Orientation="Horizontal">
<Button fa:Awesome.Content="WindowMinimize" Background="Transparent" Foreground="White" VerticalAlignment="Stretch" Padding="8" BorderThickness="0" WindowChrome.IsHitTestVisibleInChrome="True" Name="minButton" Click="MinButton_OnClick"></Button>
<Button fa:Awesome.Content="WindowMaximize" Background="Transparent" Foreground="White" VerticalAlignment="Stretch" Padding="8" BorderThickness="0" WindowChrome.IsHitTestVisibleInChrome="True" Name="maxButton" Click="MaxButton_OnClick"></Button>
<Button fa:Awesome.Content="WindowClose" Background="Transparent" Foreground="White" VerticalAlignment="Stretch" Padding="8" BorderThickness="0" WindowChrome.IsHitTestVisibleInChrome="True" Name="closeButton" Click="CloseButton_OnClick"></Button>
</StackPanel>
</Grid>
<!-- Menu Buttons-->
<Grid HorizontalAlignment="Left" VerticalAlignment="Center">
<StackPanel Orientation="Vertical">
<Button fa:Awesome.Content="Youtube" FontSize="40" Background="#00000000" Foreground="White" BorderBrush="Transparent" Width="80" Height="80" VerticalAlignment="Center" HorizontalAlignment="Center"></Button>
<Button fa:Awesome.Content="Music" FontSize="40" Background="#00000000" Foreground="White" BorderBrush="Transparent" Width="80" Height="80" VerticalAlignment="Center" HorizontalAlignment="Center"></Button>
<Button fa:Awesome.Content="Download" FontSize="40" Background="#00000000" Foreground="White" BorderBrush="Transparent" Width="80" Height="80" VerticalAlignment="Center" HorizontalAlignment="Center"></Button>
</StackPanel>
</Grid>
</StackPanel>
</Window>
The problem is your root element. Replace the StackPanel by a grid and problem solved.
Bonus : if you are new to WPF, I show you how to refactorize your styles.
<Grid Background="Black">
<Grid.Resources>
<!-- Exemple of a style with a key to reuse -->
<Style x:Key="LeftButtonStyle" TargetType="Button">
<Setter Property="FontSize" Value="40" />
<Setter Property="Width" Value="80" />
<Setter Property="Height" Value="80" />
<Setter Property="Background" Value="#00000000" />
<Setter Property="Foreground" Value="White" />
<Setter Property="BorderBrush" Value="Transparent" />
</Style>
</Grid.Resources>
<!-- TitleBar buttons -->
<StackPanel
HorizontalAlignment="Right"
VerticalAlignment="Top"
Orientation="Horizontal">
<StackPanel.Resources>
<!-- Exemple of a implicit styles that will be set to each child with a matching type -->
<!-- Notice there is no x:Key -->
<Style TargetType="Button">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Padding" Value="8" />
<Setter Property="BorderThickness" Value="0" />
</Style>
</StackPanel.Resources>
<Button Content="b1" />
<Button Content="b2" />
<Button Content="b3" />
</StackPanel>
<!-- Menu Buttons -->
<StackPanel
HorizontalAlignment="Left"
VerticalAlignment="Center"
Orientation="Vertical">
<Button Content="icon" Style="{StaticResource LeftButtonStyle}" />
<Button Content="icon" Style="{StaticResource LeftButtonStyle}" />
<Button Content="icon" Style="{StaticResource LeftButtonStyle}" />
</StackPanel>
</Grid>
Notice there is neither RowDefinitions nor ColumnDefinitions.
Here is how to do the same thing with place to set the content (a red box for exemple).
<Grid Background="Black">
<Grid.Resources>
<!-- Exemple of a style with a key to reuse -->
<Style x:Key="LeftButtonStyle" TargetType="Button">
<Setter Property="FontSize" Value="40" />
<Setter Property="Width" Value="80" />
<Setter Property="Height" Value="80" />
<Setter Property="Background" Value="#00000000" />
<Setter Property="Foreground" Value="White" />
<Setter Property="BorderBrush" Value="Transparent" />
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<!-- TitleBar buttons -->
<StackPanel
Grid.Column="1"
HorizontalAlignment="Right"
Orientation="Horizontal">
<StackPanel.Resources>
<!-- Exemple of a implicit styles that will be set to each child with a matching type -->
<!-- Notice there is no x:Key -->
<Style TargetType="Button">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Padding" Value="8" />
<Setter Property="BorderThickness" Value="0" />
</Style>
</StackPanel.Resources>
<Button Content="b1" />
<Button Content="b2" />
<Button Content="b3" />
</StackPanel>
<!-- Menu Buttons -->
<StackPanel
Grid.RowSpan="2"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Orientation="Vertical">
<Button Content="icon" Style="{StaticResource LeftButtonStyle}" />
<Button Content="icon" Style="{StaticResource LeftButtonStyle}" />
<Button Content="icon" Style="{StaticResource LeftButtonStyle}" />
</StackPanel>
<Grid Background="Red" Grid.Row="1" Grid.Column="1"/>
</Grid>

How to delete rounded edges of ToolBar without control template?

I try to do it next way:
<ToolBar x:Name="toolBar" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.Row="0">
<Button BorderBrush="Black" Content="READ" Click="Button_Click_1"/>
<ToolBar.Resources>
<Style x:Key="ToolBarMainPanelBorderStyle" TargetType="{x:Type Border}">
<Setter Property="CornerRadius" Value="0,0,0,0"/>
</Style>
</ToolBar.Resources>
</ToolBar>
It doesn't work. I don't want to change style of whole ToolBar using template. How to do it?
It can be achieved by putting your Toolbar inside the ToolBarTray as follow,
<ToolBarTray>
<ToolBar x:Name="toolBar" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.Row="0">
<Button BorderBrush="Black" Content="READ" Click="Button_Click_1"/>
<ToolBar.Resources>
<Style x:Key="ToolBarMainPanelBorderStyle" TargetType="{x:Type Border}">
<Setter Property="CornerRadius" Value="0,0,0,0"/>
</Style>
</ToolBar.Resources>
</ToolBar>
</ToolBarTray>

WPF StackPanel content vertical alignment

Is there a way in XAML to say that I want to center-align vertically all components inside a horizontal-oriented StackPanel?
I achieve the desired result with the below XAML:
<StackPanel Orientation="Horizontal">
<TextBlock VerticalAlignment="Center"/>
<Button VerticalAlignment="Center"/>
<TextBox VerticalAlignment="Center"/>
<Button VerticalAlignment="Center"/>
<TextBlock VerticalAlignment="Center"/>
</StackPanel>
But I need to repeat the VerticalAlignment="Center" for each control separately.
Is there a way to declare on the StackPanel level something like below?
<StackPanel Orientation="Horizontal" VERTICALCONTENTALIGNMENT="Center">
<TextBlock/>
<Button/>
<TextBox/>
<Button/>
<TextBlock/>
</StackPanel>
Put the StackPanel inside a Grid and set VerticalAlignment="Center" on the StackPanel
<Grid>
<StackPanel VerticalAlignment="Center">
...
</StackPanel
</Grid>
You can define style for StackPanel with Trigger which sets VerticalAlignment of all children:
<Style x:Key="HorizontalStackPanel" TargetType="{x:Type StackPanel}">
<Setter Property="Orientation" Value="Horizontal" />
<Style.Triggers>
<Trigger Property="Orientation" Value="Horizontal">
<Setter Property="FrameworkElement.VerticalAlignment" Value="Center" />
</Trigger>
</Style.Triggers>
</Style>
And apply this style:
<StackPanel Style="{StaticResource HorizontalStackPanel}">
<TextBlock />
<Button />
<TextBox />
<Button />
<TextBlock />
</StackPanel>
It works for me.
The whole code:
<Window x:Class="WpfApplication11.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="HorizontalStackPanel" TargetType="{x:Type StackPanel}">
<Setter Property="Orientation" Value="Horizontal" />
<Style.Triggers>
<Trigger Property="Orientation" Value="Horizontal">
<Setter Property="FrameworkElement.VerticalAlignment" Value="Center" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<StackPanel Style="{StaticResource HorizontalStackPanel}">
<TextBlock Text="One"/>
<Button Content="Two"/>
<TextBox Text="Three"/>
<Button Content="Four"/>
<TextBlock Text="Five"/>
</StackPanel>
</Grid>
</Window>
Define a style like this;
<Style x:Key="StackHorizontal" TargetType="StackPanel">
<Style.Resources>
<Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</Style.Resources>
</Style>
Just use this:
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<TextBlock/>
<Button/>
<TextBox/>
<Button/>
<TextBlock/>
</StackPanel>

How do I change the Foreground color of a label in a custom button when the button is enabled or disabled?

Given the following WPF Button with custom content, how do I use a Trigger to change the Foreground color of its label to blue when the button is enabled, and red when its disabled?
<Window x:Class="CustomButtonTriggerExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<Button IsEnabled="{Binding ElementName=chkEnabled, Path=IsChecked}">
<StackPanel Orientation="Horizontal">
<Label VerticalContentAlignment="Center">This is a label control inside a button</Label>
<Image Height="50" Width="50" Source="/CustomButtonTriggerExample;component/Images/Some Image.png" Stretch="Fill" />
</StackPanel>
</Button>
<CheckBox x:Name="chkEnabled">Button Enabled</CheckBox>
</StackPanel>
</Grid>
</Window>
<Window x:Class="CustomButtonTriggerExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<Button IsEnabled="{Binding ElementName=chkEnabled, Path=IsChecked}">
<Button.Resources>
<Style TargetType="Label">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type Button}}, Path=IsEnabled}" Value="False">
<Setter Property="Foreground" Value="Red" />
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type Button}}, Path=IsEnabled}" Value="True">
<Setter Property="Foreground" Value="Blue"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Resources>
<StackPanel Orientation="Horizontal">
<Label VerticalContentAlignment="Center">This is a label control inside a button</Label>
<Image Height="50" Width="50" Source="/CustomButtonTriggerExample;component/Images/Some Image.png" Stretch="Fill" />
</StackPanel>
</Button>
<CheckBox x:Name="chkEnabled">Button Enabled</CheckBox>
</StackPanel>
</Grid>
</Window>

Question about WPF Resources/Styles & Scope

i am just beginning WPF and wonder why this works
<Window ...>
<Window.Resources>
<Style x:Name="buttonStyle">
<Style.Setters>
<Setter Property="Button.FontWeight" Value="Bold" />
<Setter Property="Button.Foreground" Value="Aqua" />
</Style.Setters>
</Style>
</Window.Resources>
<Grid>
<StackPanel>
<Button ... Style="{StaticResource buttonStyle}" />
</StackPanel>
</Grid>
</Window>
but this fails,
<Window ...>
<Window.Resources>
<Style x:Name="buttonStyle">
<Style.Setters>
<Setter Property="Button.FontWeight" Value="Bold" />
<Setter Property="Button.Foreground" Value="Aqua" />
</Style.Setters>
</Style>
</Window.Resources>
<Grid>
<StackPanel ...>
<StackPanel.Resources>
<Style x:Name="buttonStyle2">
<Setter Property="Button.Foreground" Value="Red" />
</Style>
</StackPanel.Resources>
<Button ... Style="{StaticResource buttonStyle}" />
<Button ... Style="{StaticResource buttonStyle2}" />
</StackPanel>
</Grid>
</Window>
the error is
The resource "buttonStyle2" could not be resolved
The resource "buttonStyle" could not be resolved
buttonStyle resolves ok in the 1st code (without the 2nd button)
arr... my bad, i should be using x:Key not x:Name

Resources