In my WP8 application I use a ProgressIndicator and I'd like it to fade out before making it invisible. I can't find any documentation describing how I can do that, the only exposed property of ProgressIndicator is IsVisible which does not provide any animation.
Yet in some applications I can clearly see progress bar fading out.
So how can I make it fade out?
Unfortunately you can't animate the Shell components of WP7/WP8 beyond their default animations. As ProgressIndicator & SystemTray are part of the Shell UI (alongside with ApplicationBar, MessageBox and others) you'll have to settle for the buit-in transitions.
If this really troubles you, you can always recreate the ProgressIndicator exprience with a managed ProgressBar as part of your app's <Frame /> Template.
Take a look at the DoubleAnimation class on msdn
<StackPanel>
<StackPanel.Resources>
<Storyboard x:Name="myStoryboard">
<DoubleAnimation
Storyboard.TargetName="MyProgressBar"
Storyboard.TargetProperty="Opacity"
From="1.0" To="0.0" Duration="0:0:5"
Completed="DisableMyProgressBar"/>
</Storyboard>
</StackPanel.Resources>
<ProgressBar x:Name="MyProgressBar" />
</StackPanel>
In the code behind trigger the animation when your processing is complete.
private void StopProgressBar()
{
myStoryboard.Begin();
}
You will want to disable the progress bar and reset its opacity after it fades out, so use the Completed event of the Storyboard to reset these properties.
Timeline.Completed on msdn
private void DisableMyProgressBar(object sender, EventArgs e)
{
MyProgressBar.IsEnabled = false;
MyProgressBar.Opacity = 1;
}
Related
I have a simple code in XAML and the mainpage:
<Grid>
<ScrollViewer ZoomMode="Enabled" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Image Source="Assets/skyline.jpg" KeyDown="Image_KeyDown">
</Image>
</ScrollViewer>
</Grid>
When I start the programm now, i can scroll with my touchpad, but not with the arrow keys on the keyboard. Why is it like this and how can I change this behaviour? I'm asking this question because I have a much more complex example, where it just works (of course, that example is not only an image). Thank you!
The ScrollViewer responds to unhandled keyboard events that bubble up from its content. In your example you're not seeing keyboarding scroll because neither the Image nor the ScrollViewer are focusable which means there won't be any keyboard events that bubble up to or originate from the ScrollViewer. Image derives from FrameworkElement which doesn't have the concept of focus. ScrollViewer could receive focus. But, by default, it doesn't because its default control style has IsTabStop = "False".
The simple solution here is to set IsTabStop = "True" on the ScrollViewer. Now that its focusable you will start seeing around the ScrollViewer the thick focus rect automatically drawn by the system. You can disable that by also setting the UseSystemFocusVisuals="False".
In markup...
<ScrollViewer x:Name="scrollviewer"
IsTabStop="True" UseSystemFocusVisuals="False"
ZoomMode="Enabled" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Image Source="Assets/skyline.jpg">
</Image>
</ScrollViewer>
Note: This is only necessary because there isn't anything in the content that could receive focus. In more complex scenarios you'll often have something in the ScrollViewer that can be focused (e.g. a 'foo' Button). In those scenarios scrolling happens via keyboarding as you'd expect because some 'foo' has focus.
You could use the ChangeView method of ScrollViewer to scroll in Window.Current.CoreWindow.KeyDown event handler.
Please refer to the following code sample:
<ScrollViewer x:Name="scrollviewer" ZoomMode="Enabled" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Image Source="Assets/skyline.jpg">
</Image>
</ScrollViewer>
public MainPage()
{
this.InitializeComponent();
Window.Current.CoreWindow.KeyDown += CoreWindow_KeyDown;
}
private double horizontalOffset;
private double verticalOffset;
private double step = 5;
private void CoreWindow_KeyDown(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs args)
{
Debug.WriteLine("horizontalOffset: "+horizontalOffset+ " verticalOffset: "+verticalOffset);
switch (args.VirtualKey)
{
case Windows.System.VirtualKey.Left: horizontalOffset = horizontalOffset-step<0 ? 0:horizontalOffset - step; scrollviewer.ChangeView(horizontalOffset,verticalOffset,1); break;
case Windows.System.VirtualKey.Right: horizontalOffset = horizontalOffset+step>scrollviewer.ScrollableWidth?scrollviewer.ScrollableWidth: horizontalOffset + step; scrollviewer.ChangeView(horizontalOffset,verticalOffset,1);break;
case Windows.System.VirtualKey.Up: verticalOffset= verticalOffset - step < 0?0:verticalOffset- step; scrollviewer.ChangeView(horizontalOffset,verticalOffset,1);break;
case Windows.System.VirtualKey.Down: verticalOffset = verticalOffset + step > scrollviewer.ScrollableHeight?scrollviewer.ScrollableHeight:verticalOffset+ step; scrollviewer.ChangeView(horizontalOffset,verticalOffset,1);break;
default: break;
}
}
I have 3 panorama items, and I would like only the 1st to have an app bar.
So I started to implement removing the app bar for the other panorama items.
What I did was to handle SelectionChanged event and based on Panorama.SelectedIndex hide the application bar:
this.ApplicationBar.IsVisible = this.Panorama.SelectedIndex == 0;
When swiping to the 2nd item, the usual panorama animation does not work anymore, the transition animation is gone, it's sudden.
Instead of changing IsVisible, I also tried with the same result:
remove app bar this.ApplicationBar = null
set opacity to zero this.ApplicationBar.Opacity = 0
What's interesting is that animation is broken even if changing opacity to let's say 0.5
My feeling is that layout change event in the app bar generate this Panorama broken behavior.
I haven't yet been able to find a solution.
put the whole panorama in а stackpanel
<StackPanel>
<phone:Panorama Title="my application">
<phone:PanoramaItem Header="first item"/>
<phone:PanoramaItem Header="second item" Tap="OnPanoramaItemTap"/>
</phone:Panorama Title="my application">
</StackPanel>
private void OnPanoramaItemTap(object sender, System.Windows.Input.GestureEventArgs e)
{
ApplicationBar.IsVisible = false;
}
It's just an idea, but it's working, i hope it's good for your case
I've got a storyboard that should play when a page loads. Is there any way to do that directly from Expression Blend? I'd rather not do it through code or xaml.
What about doing the same for button clicks or other events?
Thanks
You can drag the ControlStoryboardAction behaviour (Assets->Behaviors) over to the Page, and set the EventName to be PageLoaded, and ControlStoryboardOption to Play, and Storyboard to your storyboard.
If you decide to do this via code then all you need to do is just to call Begin() of the StoryBoard. Like for example:
<Storyboard x:Name="fadeIn">
<DoubleAnimation Storyboard.TargetName="img"
Storyboard.TargetProperty="Opacity" From="0.0"
To="1.0" Duration="0:0:1" />
</Storyboard>
private void btnFadeIn_Click(object sender, RoutedEventArgs e)
{
this.fadeIn.Begin();
}
Question:
Get scroll event for ScrollViewer on Windows Phone
I have a scrollviewer like so:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ScrollViewer x:Name="MyScroller">
<StackPanel>
<!-- ... -->
</StackPanel>
</ScrollViewer>
</Grid>
I need the event for when the scrolling occurs for MyScroller:
// MyScroller.Scroll += // <-- "Scroll" event does not exist on ScrollViewer
MyScroller.MouseWheel += MyScroller_MouseWheel; // Does not fire on scroll
MyScroller.ManipulationDelta += MyScroller_ManipulationDelta; // Fires for pinch-zoom only
MouseMove fires when ScrollViewer is scrolled:
public MainPage()
{
InitializeComponent();
MyScroller.MouseMove += MyScroller_MouseMove;
}
void MyScroller_MouseMove(object sender, MouseEventArgs e)
{
throw new NotImplementedException();// This will fire
}
It isn't intuitive, since it is named as a "mouse" event and there is no mouse on the phone. The touch point does move, however, relative to the ScrollViewer container, which is how it can handle scrolling.
It's not that simple, but there's a few scroll detection mechanisms written in this question:
WP7 Auto Grow ListBox upon reaching the last item
Basically take a look at the way OnListVerticalOffsetChanged is called and used.
With Mango, you can watch for the "ScrollStates" visual state to change as described in this sample project.
I have a control with white text foreground color and transparent background color.
Later on this usercontrol will be added into a different control that carries the real background color.
However during designing this, control due white foreground on white background in VS 2010, I can't obviously see anything. In there anyway to define a different color for just the design time?
I have tried this:
if (System.ComponentModel.DesignerProperties.IsInDesignTool)
{
LayoutRoot.Background = new SolidColorBrush(Colors.Blue);
}
But this doesn't work. Any tips?
UPDATE:
I dont understand how this works for you guys. I have created a new Silverlight 4.0 Application and have inserted this line of code into the ctor:
public MainPage()
{
InitializeComponent();
LayoutRoot.Background = new SolidColorBrush(Colors.Blue);
}
<UserControl x:Class="SilverlightApplication3.MainPage"
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"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot">
</Grid>
</UserControl>
When I go into Designer, I still dont see it as blue. And I dont even have any isInDesignTime Condition there. What I am missing here?
Thanks,
Kave
Here's one way:
if (System.ComponentModel.DesignerProperties.IsInDesignTool)
{
LayoutRoot.Background = new SolidColorBrush(Colors.Yellow);
}
If you switch to creating a templated control, you'll need to wait to set things up in OnApplyTemplate, like in this example:
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
Border b = this.GetTemplateChild("backBorder") as Border;
if (b != null && System.ComponentModel.DesignerProperties.IsInDesignTool)
{
b.Background = new SolidColorBrush(Colors.Orange);
}
}
Assuming this is the template:
<Style TargetType="local:TemplatedControl1">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:TemplatedControl1">
<Border x:Name="backBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I also like to add conditional compile directives around code like this, as it's only for the developer/designer and is never needed at run-time.
#if DEBUG
if (System.ComponentModel.DesignerProperties.IsInDesignTool)
{
LayoutRoot.Background = new SolidColorBrush(Colors.Yellow);
}
#endif
Note that this entire technique works only when the UserControl you're creating is used within* another* UserControl/Control at design time. So, if the code I suggested above is placed in a UserControl named UserControlWithDesignMode, then you must have another UserControl, UserControlHost, that contains an instance of the UserControlWithDesignMode control to see the behavior work at design time. The code-behind for the currently edited control does not execute when you're editing it. It only executes when it's contained within another host (in Silverlight, another UserControl for example).
One option would be to give the UserControl a background color, and then override that where you use it. So when you're editing the UserControl in isolation, it would have a background color; but when you're editing a control that contains that UserControl, you would see it with the transparent background like you want.
So the UserControl's XAML file would look like this:
<UserControl x:Class="MyUserControl" ... Background="DarkBlue">
And then in some other screen, where you use it, you could do:
<my:MyUserControl Background="Transparent" ...>
Inelegant, but simple.
Alternate approach that doesn't involve code:
Install the "Visual Studio 2012 Color Theme Editor" found here:
http://visualstudiogallery.msdn.microsoft.com/366ad100-0003-4c9a-81a8-337d4e7ace05
Or for VS 2010: http://visualstudiogallery.msdn.microsoft.com/20cd93a2-c435-4d00-a797-499f16402378
Create a new custom theme based on the one you want to modify.
Click the "Show All Elements" filter button in the upper-left of the theme editor
Type "artboard" in the search-box in the upper-right of the theme editor
Set the "Cider -> ArtboardBackground" color to a different color of your choice.
Yay! :D
Note: the "Cider -> ArtboardBackground" color theme field is found in VS2012 but I cannot confirm whether it has the same name in VS2010
You can use following code within UserControl constructor:
For WPF:
if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
{
LayoutRoot.Background = new SolidColorBrush( Colors.Blue );
}
For WPF / Silverlight:
if (DesignerProperties.GetIsInDesignMode( this ))
{
LayoutRoot.Background = new SolidColorBrush( Colors.Blue );
}
Good thread, especially when doing some MVVM the fact that UserControls appear on white when they are transparent is very annoying.
I'm sure you could do this in Blend with a state defined based on whether a designer is running, but I don't think that'd reduce the amount of work.
Still not sure how to avoid the code in the code behind and avoiding having to open blend, so if anybody has suggestions thanks in advance for posting.
I would suggest to use Opacity
<my:MyUserControl Background="Transparent" ...>
That doesn't work, since it will make any child controls inside the usercontrol invisible at run time.
One option would be to give the UserControl a background color, and then override that where you use it.
Did you try to set the Background on the UserControl? Not sure why but for me it doesn't work.
What does work is to set the Background of the Content, like so
<UserControl x:Class="...">
<StackPanel Background="{StaticResource PhoneChromeBrush}">
...
then putting the following code in the constructor of the view
public View() {
InitializeComponent();
var c = Content as Panel;
if (c != null) c.Background = new SolidColorBrush(Colors.Transparent);
}
Another technique mentioned in this SO question is to use the undocumented property d:DesignerProperties.DesignStyle, which works great for applying a design-time-only style to a single control, but which doesn't appear to work for a Style in a ResourceDictionary that would apply to all of the appropriately-typed controls or elements under the scope of the dictionary.
To solve this, on that same page I provide a simple solution for deploying a designer-only style into a ResourceDictionary. Here is a summary of that answer:
First, put the desired style in a XAML dictionary in the normal way.
<Window.Resources>
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="True" />
</Style>
</Window.Resources>
Then, in the C# code, remove the style from the ResourceDictionary when design mode is not detected. Do this is in the OnInitialized override:
protected override void OnInitialized(EventArgs e)
{
if (DesignerProperties.GetIsInDesignMode(this) == false)
Resources.Remove(typeof(TreeViewItem));
base.OnInitialized(e);
}
Design Mode: Runtime Mode: