UWP Button pressed image - xaml

I'm working on a UWP app targeted phones and tablets, and am currently implementing a feature for taking a picture with the camera.
I've put a button control on the camera preview, and used an icon to represent the button (see XAML code below).
My problem is, that when i press the button, it turns into a semi transparent grey square, which is far from the green cirle I'm using as icon.
How can I use an other icon for when the button is pressed
<Grid >
<!--Camera preview-->
<CaptureElement Name="PreviewControl" Stretch="Uniform"/>
<Button Tapped="btnCancel_Tapped" Name="btnCancel" Margin="5,0,0,10" HorizontalAlignment="Left" VerticalAlignment="Bottom" Height="50" Width="65">
<Button.Background>
<ImageBrush ImageSource="/Assets/images/btn_cancel.png">
</ImageBrush>
</Button.Background>
</Button>
<Button HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,0,0,5" Name="btnPhoto" Tapped="btnPhoto_Tapped" IsEnabled="False" Width="70" Height="70">
<Button.Background>
<ImageBrush ImageSource="/Assets/Images/btn_takepicture_off.png">
</ImageBrush>
</Button.Background>
</Button>
</Grid>

To set an image on press you need to edit button template and edit "pressed" state
just add this code in page resources and edit path to image:
<Style x:Key="ButtonStyle1" TargetType="Button">
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundTransparentBrush}"/>
<Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}"/>
<Setter Property="Padding" Value="8,4,8,4"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
<Setter Property="UseSystemFocusVisuals" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid x:Name="RootGrid" Background="{TemplateBinding Background}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<PointerUpThemeAnimation Storyboard.TargetName="RootGrid"/>
</Storyboard>
</VisualState>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseMediumLowBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseHighBrush}"/>
</ObjectAnimationUsingKeyFrames>
<PointerUpThemeAnimation Storyboard.TargetName="RootGrid"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="RootGrid">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<ImageBrush ImageSource="SET YOUR IMAGE HERE.jpg"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightTransparentBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseHighBrush}"/>
</ObjectAnimationUsingKeyFrames>
<PointerDownThemeAnimation Storyboard.TargetName="RootGrid"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="RootGrid">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseLowBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledTransparentBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTransitions="{TemplateBinding ContentTransitions}" Content="{TemplateBinding Content}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
and apply this style to your button:
Button Style="{StaticResource ButtonStyle1}"

If i were you, I'd make that image inside of the Button's template.
It not only will get rid of unwanted existing elements/looks of the button (such as they grey square), it will also allow you to easily give it behaviors such as what it does when you mouse-over / press it.
To do this in the most simplistic way, paste the following inside your <Button></Button>:
<Button.Template>
<ControlTemplate TargetType="Button">
[[Anything you want your button to be made of goes here]]
</ControlTemplate>
</Button.Template>
In the area I marked "[[Anything you want your button to be made of goes here]]" you can now build exactly what you want your button to look like with anything from <Grid/> to <Image/> to simplistic parts such as <Ellipse/> or <Rectangle/>

I use the following code when changing a button picture once clicked:
Add the following USING STATEMENTS:
using System;
using Windows.UI.Xaml.Media.Imaging;
In the click event, add this code:
PicA.Source= new BitmapImage() { UriSource = new Uri("ms-appx:///Assets/6.png", UriKind.Absolute) };
<--- the PicA represents an image (from the toolbox) and 6.png is my new picture from my assets folder.
If you need to replace your image later back to the original, then just copy/paste the above code and change the picture name (6.png to whatever) back to your original.
Johnny Smith - Shetland Islands UK

Here is another example using the TAPPED event:
private void MyBox_Tapped(object sender, TappedRoutedEventArgs e)
{
var image = sender as Image;
var bitmapImage = image?.Source as BitmapImage;
if (bitmapImage != null)
{
var source = bitmapImage.UriSource.LocalPath;
if (source == "/Assets/Green1 (Custom).png")
{
MyBox.Source = new BitmapImage() { UriSource = new Uri("ms-appx:///Assets/Red1 (Custom).png", UriKind.Absolute) };
}
else if (source == "/Assets/Red1 (Custom).png")
{
MyBox.Source = new BitmapImage() { UriSource = new Uri("ms-appx:///Assets/Green1 (Custom).png", UriKind.Absolute) };
}
}
<--- The above code allows for inter-changing of two images (unlimited on a multitude of IF statements - endless!). All you need to do is add your coding after each of the 'MyBox' statements to do whatever your programming requires thereafter.
If you combine my earlier reply by using a button click event, then one only requires to add the coding as listed above - meaning a single button click can be used to do many tasks, and also using many different images. The scope is endless as you can use unlimited IF statements throughout your coding within each segment of your coding thereafter. Hope this helps you all... Johnny

You can also use WintRT ToolKit available on NuGet:
https://www.nuget.org/packages/winrtxamltoolkit/
From this Toolkit you can use ImageButton that is a custom Button control that takes one to three images to be used to represent different states of the button: normal, hover, pressed, disabled).
Here is XAML sample of usage:
<toolkit:ImageButton NormalStateImageSource="ms-appx:///Assets/normal_button_state.png"
PressedStateImageSource="ms-appx:///Assets/pressed_button_state.png"/>
Remember to add using xmlns at the top of you page:
xmlns:toolkit ="using:WinRTXamlToolkit.Controls"

Related

How to implement the edge button pointer event?

I have seen this kind of button styling only in edge button and would like to know how to implement it. So there are two different effects into play(as far as I know). First that when buttons are pressed the content inside them shrinks (unlike default effect provided by Windows) and then second a dark non-discrete border appears inside the button when clicked to almost give a feel of depth in it.
This question was a challenge!
My first idea was to use the UWP Community Toolkit DropShadowPanel to create a shadow and clip it to the button's rectangle. Unfortunately this didn't work well, as I would have to set the shadow on a Rectangle that would need to have a visible border, which is not really good for our purpose of having a nicely blended borderless button. In addition, the DropShadowPanel shadow just didn't give a strong enough shadow effect that would be enough for the button to look like in Edge.
I have used Visual Studio and attached it's debugger to the Edge browser to see which control does the browser actually use. The Live Tree Visualizer revealed this:
SpartanXAML.InnerShadowControl? Okay, we don't have that. Let's work around this.
I fired up Photoshop instead. Created a 64x64 square image, put a transparent rectangle layer on the surface and set its Inner Glow as shown in this screenshot:
After export, I got the following PNG:
That looks quite like the inner shadow on the Edge button!
Now let's create a custom button style that uses this image!
<Style TargetType="Button" x:Key="EdgeButtonStyle">
<Setter Property="Background" Value="#f5f5f5" />
<Setter Property="Foreground" Value="{ThemeResource ButtonForeground}" />
<Setter Property="BorderBrush" Value="{ThemeResource ButtonBorderBrush}" />
<Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}" />
<Setter Property="Padding" Value="8" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
<Setter Property="UseSystemFocusVisuals" Value="True" />
<Setter Property="FocusVisualMargin" Value="-3" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid x:Name="RootGrid" Width="64" Height="64" Background="{TemplateBinding Background}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<PointerUpThemeAnimation Storyboard.TargetName="RootGrid" />
</Storyboard>
</VisualState>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="#c1c1c0" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundPointerOver}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="#c1c1c0" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundPressed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Scale" Storyboard.TargetProperty="ScaleX">
<DiscreteObjectKeyFrame KeyTime="0" Value="0.8" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Scale" Storyboard.TargetProperty="ScaleY">
<DiscreteObjectKeyFrame KeyTime="0" Value="0.8" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="InnerShadow" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundDisabled}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundDisabled}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Content="{TemplateBinding Content}"
ContentTransitions="{TemplateBinding ContentTransitions}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Padding="{TemplateBinding Padding}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
AutomationProperties.AccessibilityView="Raw">
<interactivity:Interaction.Behaviors>
<behaviors:Scale x:Name="Scale"
ScaleX="1"
ScaleY="1"
CenterX="32"
CenterY="32"
Duration="100"
Delay="0"
EasingType="Default"
AutomaticallyStart="True"/>
</interactivity:Interaction.Behaviors>
</ContentPresenter>
<Image Source="/Assets/InnerShadowGray.png" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Visibility="Collapsed" x:Name="InnerShadow" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This is a lengthy listing so I will just point out the most interesting things:
Removed all borders from the button
Set background to #f5f5f5 and hover background to #c1c1c0 to match Edge
Set the width and height to 64
Added an Image as the last control in the RootGrid, this is the shadow image, is Collapsed by default and appears only when pointer is pressed
Used UWP Community Toolkit's (Microsoft.Toolkit.Uwp.UI.Controls NuGet package) Scale behavior to create a simple, easy to control animation. This required adding xmlns:interactivity="using:Microsoft.Xaml.Interactivity" and xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Animations.Behaviors" XML namespaces to the root element of the file
Replaced the default PointerDownThemeAnimation with a custom animation utilizing Scale behavior, to make the animation more significant and scale uniformly, without skewing the content
Now let's just take our new button for a test ride!
<Button Style="{StaticResource EdgeButtonStyle}" HorizontalAlignment="Center">
<Image Source="Assets/Windows.png" />
</Button>
And the result:

Styling controls: How to overwrite the styles in different 'VisualState's (PointerOver, Pressed, ...)

How does one handle hover states and so on?
One could overwrite a brush like SystemControlHighlightBaseHighBrush for a Button:
<SolidColorBrush x:Key="SystemControlHighlightBaseHighBrush" Color="White" />
If any other control uses that brush, it also takes this value, which is not desired. The other option I found is to overwrite the default style:
<!-- Default style for Windows.UI.Xaml.Controls.Button -->
<Style TargetType="Button">
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}" />
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundTransparentBrush}" />
<Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}" />
<Setter Property="Padding" Value="8,4,8,4" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
<Setter Property="UseSystemFocusVisuals" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid x:Name="RootGrid" Background="{TemplateBinding Background}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<PointerUpThemeAnimation Storyboard.TargetName="RootGrid" />
</Storyboard>
</VisualState>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseMediumLowBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseHighBrush}" />
</ObjectAnimationUsingKeyFrames>
<PointerUpThemeAnimation Storyboard.TargetName="RootGrid" />
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundBaseMediumLowBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightTransparentBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseHighBrush}" />
</ObjectAnimationUsingKeyFrames>
<PointerDownThemeAnimation Storyboard.TargetName="RootGrid" />
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseMediumLowBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledTransparentBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Content="{TemplateBinding Content}"
ContentTransitions="{TemplateBinding ContentTransitions}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Padding="{TemplateBinding Padding}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
AutomationProperties.AccessibilityView="Raw"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Here I would change the values in ObjectAnimationUsingKeyFrames. But what is if the default styling changes in an upcoming version of Windows?
Currently I see no other way than overwriting the default style. Perhaps one could overwrite some events and set e.g. the border color there. But I think there are not always all events available and you would have to write your custom button everytime.
It looks somehow wrong to me to overwrite a complete style for changing only one value. How do you handle such cases?
TL;DR: Yes, changing the complete template (not style) is the most used scenario.
There are different points to consider here:
You want all of your controls to have a consistent layout across your application.
So my first option would be to define a new theme for your application and indeed overwrite the SystemControlHighlightBaseHighBrush and other ThemeResource resources required to accomplish your new branding.
You only want a single control to change layout.
If for some valid reason you don't want all controls using the ThemeResource to change to your new theme, you will have to overwrite the complete control template (as the template is one block and thus an all or nothing). There is no need to overwrite all other property setters (like Foreground, Background, Padding, ... in your example).
If you're very lucky, the property you're trying to change is a templated property and you can simply use a single property setter to fix your layout.
The downside with this approach is indeed that future versions of the SDK can change the template of a given control. An example of this are the GridView/GridViewItem styles between Windows 8/8.1 and 10. So far there has mostly been a backward compatibility on styles, meaning your app will continue to work but might not be in line with the latest layout guidelines or miss some performance improvements. It's therefor 'best practice' to re-apply custom layout changes on the newest templates (if time permits).
A 'dirty' solution is 'hacking' into the Visual Tree to change properties at runtime (based on events, ...). But this won't prevent you from possible breaking changes on future SDK updates either, so I wouldn't even consider this as a valid option.
Going with custom controls
The final approach is going with a custom control, define your own template (again the same problem with newer SDK versions) or use the default template and override OnApplyTemplate and tweak the property you'd like to change by getting it from the Visual Tree. But same remarks apply here that a future SDK version might drop the control/state in your tree and break your code.
Conclusion: either option you choose, there's a possibility future SDK versions will break your implementation.

Windows Phone 8.1 AppBarButton Template not editable

I am not able to redefine the Template of an AppBarButton inside BottomAppBar in a Windows Phone 8.1 project.
In Visual Studio XAML designer it changes (it shows "button 2" text), but when I deploy it to the phone or to the emulator, the default template is applied.
I tried to right click the control, "Edit template", "Edit a copy...", but it's not available. Is it possible, to redefine this template?
My XAML code (just a very simplified example):
<Page.BottomAppBar>
<CommandBar>
<CommandBar.SecondaryCommands>
<AppBarButton
Label="button">
<AppBarButton.Template>
<ControlTemplate>
<TextBlock
Text="button 2" />
</ControlTemplate>
</AppBarButton.Template>
</AppBarButton>
</CommandBar.SecondaryCommands>
</CommandBar>
</Page.BottomAppBar>
I have Windows 8.1 Pro with Visual Studio Community 2013 Update 4 installed.
No, it is not possible to customize the app bar on Windows Phone 8.1 beyond the foreground and background colors. On Windows Phone the app bar is system UI rather than app as UI.
If you want to customize your app bar buttons you can put them in a custom panel docked at the bottom of the page instead of in a Page.BottomAppBar
You can definitely right click and edit a copy. I just did this recently. Try putting a temporary AppBarButton at the top of your page and right click that one. Here is the default style in case you need it:
<Style x:Key="AppBarButtonStyle1" TargetType="AppBarButton">
<Setter Property="Foreground" Value="{ThemeResource AppBarItemForegroundThemeBrush}"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="AppBarButton">
<StackPanel x:Name="LayoutRoot" Background="Transparent" Width="80">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ApplicationViewStates">
<VisualState x:Name="FullSize"/>
<VisualState x:Name="Compact">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="TextLabel">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Width" Storyboard.TargetName="LayoutRoot">
<DiscreteObjectKeyFrame KeyTime="0" Value="48"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke" Storyboard.TargetName="Ellipse">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource AppBarItemForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="Ellipse">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource AppBarItemForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="Content">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource AppBarItemPressedForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke" Storyboard.TargetName="Ellipse">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource AppBarItemDisabledForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="Content">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource AppBarItemDisabledForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="TextLabel">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource AppBarItemDisabledForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid HorizontalAlignment="Center" Height="38.5" Margin="0,12,0,4" Width="38.5">
<Ellipse x:Name="Ellipse" Fill="{ThemeResource AppBarItemBackgroundThemeBrush}" Height="38.5" Stroke="{ThemeResource AppBarItemForegroundThemeBrush}" StrokeThickness="2.5" UseLayoutRounding="False" Width="38.5"/>
<Grid x:Name="ContentRoot" Background="Transparent">
<ContentPresenter x:Name="Content" AutomationProperties.AccessibilityView="Raw" Content="{TemplateBinding Icon}" Foreground="{TemplateBinding Foreground}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Grid>
</Grid>
<TextBlock x:Name="TextLabel" Foreground="{ThemeResource AppBarItemForegroundThemeBrush}" FontSize="9.5" FontFamily="{TemplateBinding FontFamily}" Margin="0,0,0,10.5" TextAlignment="Center" TextWrapping="Wrap" Text="{TemplateBinding Label}" Width="70.5"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Styling TextBox/PasswordBox in XAML

I've been wondering if there is a simpler way to change just one attribute then restyling the whole ControlTemplate in Windows Phone 8.
I recently found myself in need to change PasswordBox's background (the background shown when selected/typing into it) without changing anything else. I know there is the way of recreating the whole ControlTemplate (since it's HUGE for my taste and I'm getting a bit lost in it - I'm a rookie).
Are the other (preferably easier) options how to do it? If so, which?
The reason I'm asking is because I'm creating App that needs to look pretty much the same on Android, iOS and Windows Phone (android & iOS apps are done by someone else, I'm working on WP App and the design is given).
The App needs to look the same regardles of theme chosen by user on his phone.
And since the text is white and in dark theme when writing into TextBox/PasswordBox, the background is also changed to white - the result being you can't see what you're typing.
Is it easier to change "Foreground-when-typing" or "background-when-typing"? How to do it without recreating the whole ControlTemplate?
The way to do this is with retemplating and implicit styling.
Don't be scared. It's easy, see, here's what you're after:
<phone:PhoneApplicationPage.Resources>
<Style TargetType="TextBox">
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}"/>
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/>
<Setter Property="Background" Value="Black"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderBrush" Value="White"/>
<Setter Property="SelectionBackground" Value="White"/>
<Setter Property="SelectionForeground" Value="Black"/>
<Setter Property="CaretBrush" Value="White"/>
<Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/>
<Setter Property="Padding" Value="2"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Grid Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="MainBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="MainBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentElement">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="ReadOnly">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="MainBorder">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ReadonlyBorder">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ReadonlyBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ReadonlyBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentElement">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxReadOnlyBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<!--<VisualState x:Name="Focused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="MainBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxEditBackgroundBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="MainBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxEditBorderBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>-->
<VisualState x:Name="Unfocused"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="MainBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Margin="{StaticResource PhoneTouchTargetOverhang}"/>
<Border x:Name="ReadonlyBorder" BorderBrush="{StaticResource PhoneDisabledBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="Transparent" Margin="{StaticResource PhoneTouchTargetOverhang}" Visibility="Collapsed"/>
<Border BorderBrush="Transparent" BorderThickness="{TemplateBinding BorderThickness}" Background="Transparent" Margin="{StaticResource PhoneTouchTargetOverhang}">
<ContentControl x:Name="ContentElement" BorderThickness="0" HorizontalContentAlignment="Stretch" Margin="{StaticResource PhoneTextBoxInnerMargin}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="Stretch"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</phone:PhoneApplicationPage.Resources>
Now, whenever using a TextBox on that page it will always be white text on a black background. (Or reversed when selected.)
This:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<TextBox Text="something" />
<TextBox />
</StackPanel>
</Grid>
Creates this:
Unfortunately you can't do anything about the handles on the selection using the accent color though.
I haven't handed disabled or read-only states but they should be simple to change.

How to set textbox background transferent when readonly = true in windows phone 8

I want to set the textbox background is tranfernt when readonly = true i don't want the default color .. can anyone give me solution
I am trying this one but its not working
<TextBox Name="MyTextBox" Background="Transparent" Text="My Text" IsReadOnly="True" />
Thanks
Setting IsReadOnly on a TextBox applies certain styles to the TextBox including its Background. You can change these styles by doing the following:
Open your xaml file in Blend from within Visual Studio
In Blend, right click on your TextBox and click on Edit Template-->Edit Copy
In the next dialog, tick Application to define the new style in App.xaml and give your style a name.
Click save and close Blend.
You will see the new style that you just created is in App.xaml. You would want to change the value of Background story board target property under the ReadOnly visual state to whichever color you want.
To apply this new style to any TextBox just add Style="{StaticResource TextBoxStyle1}" to your TextBox where TextBoxStyle1 is the name you assigned to your style.
Edit:
Here is the full style, add it in App.xaml inside <Application.Resources>
<Style x:Key="TextBoxStyle1" TargetType="TextBox">
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}"/>
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/>
<Setter Property="Background" Value="{StaticResource PhoneTextBoxBrush}"/>
<Setter Property="Foreground" Value="{StaticResource PhoneTextBoxForegroundBrush}"/>
<Setter Property="BorderBrush" Value="{StaticResource PhoneTextBoxBrush}"/>
<Setter Property="SelectionBackground" Value="{StaticResource PhoneAccentBrush}"/>
<Setter Property="SelectionForeground" Value="{StaticResource PhoneTextBoxSelectionForegroundBrush}"/>
<Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/>
<Setter Property="Padding" Value="2"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Grid Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="MainBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="MainBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentElement">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="ReadOnly">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="MainBorder">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ReadonlyBorder">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ReadonlyBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="Red"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ReadonlyBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentElement">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxReadOnlyBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="MainBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxEditBackgroundBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="MainBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxEditBorderBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="MainBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Margin="{StaticResource PhoneTouchTargetOverhang}"/>
<Border x:Name="ReadonlyBorder" BorderBrush="{StaticResource PhoneDisabledBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="Transparent" Margin="{StaticResource PhoneTouchTargetOverhang}" Visibility="Collapsed"/>
<Border BorderBrush="Transparent" BorderThickness="{TemplateBinding BorderThickness}" Background="Transparent" Margin="{StaticResource PhoneTouchTargetOverhang}">
<ContentControl x:Name="ContentElement" BorderThickness="0" HorizontalContentAlignment="Stretch" Margin="{StaticResource PhoneTextBoxInnerMargin}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="Stretch"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Then in your text box you simply point to this style:
<TextBox IsReadOnly="True" Style="{StaticResource TextBoxStyle1}" />
Another approach is to set the TextBox IsHitTestVisible=false. The field is then also not editable by the user and you can set the background as usual.
By the way, setting a different border color of a disabled textbox can be done application wide programmatically:
(App.Current.Resources["PhoneDisabledBrush"] as SolidColorBrush).Color = Colors.Magenta;
RichTextBox allows a lot of customization and works well for when you want to register events. Note that IsReadOnly is set to true by default for RichTextBox so you do not need to set this property.