I need to show the images continuously like projection flip animation like the below link having sample.
http://www.silverlightbuzz.com/2009/10/14/using-the-3d-tools-to-animate-in-blend/
How to implement the above sample second animation .There are two types of animations we can see in above link .How to implement second one in windows 8 like that?
The dlls System.Windows.Interactivity and Microsoft.Expression.Interactions are n't useful in windows 8.Then how to do this animation in windows 8?
EDIT:
<UserControl.Resources>
<Storyboard x:Name="Storyboard1" RepeatBehavior="Forever">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)">
<EasingDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
<EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="0"/>
<EasingDoubleKeyFrame KeyTime="00:00:01.5000000" Value="0"/>
<EasingDoubleKeyFrame KeyTime="00:00:02" Value="90"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle1" Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationX)">
<EasingDoubleKeyFrame KeyTime="00:00:00" Value="-90"/>
<EasingDoubleKeyFrame KeyTime="00:00:02" Value="-90"/>
<EasingDoubleKeyFrame KeyTime="00:00:02.5000000" Value="0"/>
<EasingDoubleKeyFrame KeyTime="00:00:03.5000000" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle1" Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)">
<EasingDoubleKeyFrame KeyTime="00:00:03.5000000" Value="0"/>
<EasingDoubleKeyFrame KeyTime="00:00:04" Value="90"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationX)">
<EasingDoubleKeyFrame KeyTime="00:00:00" Value="-90"/>
<EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="Black">
<Rectangle x:Name="rectangle1" RadiusX="12" RadiusY="12" Height="300" HorizontalAlignment="Center" VerticalAlignment="Center" Width="300">
<Rectangle.Projection>
<PlaneProjection RotationX="-90"/>
</Rectangle.Projection>
<Rectangle.Fill>
<ImageBrush ImageSource="/Assets/7.png"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle x:Name="rectangle" RadiusX="12" RadiusY="12" Height="300" HorizontalAlignment="Center" VerticalAlignment="Center" Width="300">
<Rectangle.Projection>
<PlaneProjection RotationX="-90"/>
</Rectangle.Projection>
<Rectangle.Fill>
<ImageBrush ImageSource="/Assets/8.png"/>
</Rectangle.Fill>
</Rectangle>
<Button x:Name="StartAnimation"
Content="Start Animation"
Grid.Row="1"
Width="163"
Height="61" Margin="0,65,0,24" Click="StartAnimation_Click" />
</Grid>
link that you should follow..it will tell you how make storyboard for animation ..and when you save your storyboard in blend then a stoyboard will automatically come in page.resources section and you can begin it in your code behind whereever you want to..just right''
StoryboardName.begin();
i ma giving you this link it is very difficult to give you all information step by step as it requires ui use..hope this helps you..
ok fine i have done something that might helps you..like i have binded your rectangle fill to a property that you can change at any time through code .like you can use dispatchertimer and after fixed interval you can change the image of your rectangle like this..
<Rectangle x:Name="rectangle1" RadiusX="12" RadiusY="12" Height="300" HorizontalAlignment="Center" VerticalAlignment="Center" Width="300">
<Rectangle.Projection>
<PlaneProjection RotationX="-90"/>
</Rectangle.Projection>
<Rectangle.Fill>
<ImageBrush ImageSource="{Binding hello1}"/>
</Rectangle.Fill>
</Rectangle>
in your page .cs do this..
public sealed partial class MainPage : Page , INotifyPropertyChanged
{
public MainPage()
{
this.InitializeComponent();
DispatcherTimerSetup();
// hello1 = "/Assets/4.jpeg";
hello1 = new ImageBrush();
hello1.ImageSource =
new BitmapImage(
new Uri(BaseUri, "Assets/1.jpg")
);
this.DataContext = this;
}
DispatcherTimer dispatcherTimer;
DateTimeOffset startTime;
DateTimeOffset lastTime;
DateTimeOffset stopTime;
int timesTicked = 1;
int timesToTick = 10;
public void DispatcherTimerSetup()
{
dispatcherTimer = new DispatcherTimer();
dispatcherTimer.Tick += dispatcherTimer_Tick;
dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
//IsEnabled defaults to false
// TimerLog.Text += "dispatcherTimer.IsEnabled = " + dispatcherTimer.IsEnabled + "\n";
startTime = DateTimeOffset.Now;
lastTime = startTime;
// TimerLog.Text += "Calling dispatcherTimer.Start()\n";
dispatcherTimer.Start();
//IsEnabled should now be true after calling start
// TimerLog.Text += "dispatcherTimer.IsEnabled = " + dispatcherTimer.IsEnabled + "\n";
}
void dispatcherTimer_Tick(object sender, object e)
{
rectangle.Fill = hello1;
}
private ImageBrush hello;
public ImageBrush hello1
{
get
{
return hello;
}
set
{
hello = value;
FirePropertyChanged("hello1");
}
}
/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached. The Parameter
/// property is typically used to configure the page.</param>
private void StartAnimation_Click_1(object sender, RoutedEventArgs e)
{
Storyboard1.Begin();
// Storyboard1.GetCurrentTime =
// Storyboard1.
// double sd = Storyboard1.GetCurrentTime;
}
public event PropertyChangedEventHandler PropertyChanged;
protected void FirePropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
you can modify it according to your need..hope this will help you..
Related
I’m new to WPF NotifyIcon and I’m trying to use the Windowless Sample which uses a ResourceDictionary instead of a window and the TaskbarIcon.DataContext is set to my ViewModel. I can call the example commands (ShowWindowCommand, etc.) and it works fine.
However, in my ViewModel I can’t figure out how to reference the TaskbarIcon. I want to show a standard balloon something like NotifyIcon.ShowBallonTip(title, text, BalloonIcon.Error). I’ve tried giving the tb:TaskbarIcon an x:Name but my ViewModel still does not see it.
How do I reference the TaskbarIcon from my ViewModel? Thanks!
<tb:TaskbarIcon x:Key="NotifyIcon"
IconSource="/Red.ico"
ToolTipText="Double-click for window, right-click for menu"
DoubleClickCommand="{Binding ShowWindowCommand}"
ContextMenu="{StaticResource SysTrayMenu}">
<tb:TaskbarIcon.DataContext>
<local:NotifyIconViewModel />
</tb:TaskbarIcon.DataContext>
</tb:TaskbarIcon>
In MVVM you can't directly operate control in your VM.
VM must nothing know about View. Instead of it you must define property Icon in VM (as I see it is NotifyIconViewModel) and then in View (TaskbarIcon) you need bind it to IconSource.
VM:
public Icon { get { new System.Drawing.Icon(#"..\Properties\Icons\YourIcon.ico"); }};
View
<tb:TaskbarIcon DataContext="YourViewModel"
IconSource="{Binding Path=Icon}"
ToolTipText="Double-click for window, right-click for menu"
DoubleClickCommand="{Binding ShowWindowCommand}"
ContextMenu="{StaticResource SysTrayMenu}"/>
Here is one implementation that works fine for me...
MainWindow.xaml:
xmlns:tb="http://www.hardcodet.net/taskbar"
<tb:TaskbarIcon x:Name="TrayIcon" IconSource="icon.ico" ToolTipText="{Binding TrayIconText}" MenuActivation="RightClick"
LeftClickCommand="{Binding TrayClickCommand}">
<tb:TaskbarIcon.ContextMenu>
<ContextMenu>
<MenuItem Header="Exit" Command="{Binding CloseAppCommand}" CommandParameter="{Binding}">
<MenuItem.Icon>
<Image Source="pack://application:,,,/Resources/Img/Shutdown32.png" Style="{StaticResource MenuItemImage}"/>
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</tb:TaskbarIcon.ContextMenu>
</tb:TaskbarIcon>
MainWindow.xaml.cs:
//Subscribe to VM event:
var mvm = DataContext as MainViewModel;
mvm.DisplayTrayBalloonNotice += OnDisplayTrayBalloon;
private void OnDisplayTrayBalloon(object sender, NotificationEventArgs<string> e)
{
var balloon = new TrayBalloon { NotificationText = e.Data };
PopupAnimation pa = PopupAnimation.Fade;
TrayIcon.ShowCustomBalloon(balloon, pa, Settings.Default.NotificationDuration * 1000);
}
TrayBalloon.xaml:
<UserControl x:Class="MCPublisher.Resources.TrayBalloon"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tb="http://www.hardcodet.net/taskbar"
Height="150" Width="300">
<UserControl.Resources>
<Storyboard x:Key="FadeIn">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Grid"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" />
<SplineDoubleKeyFrame KeyTime="00:00:01" Value="0.95" />
<SplineDoubleKeyFrame KeyTime="00:00:03" Value="0.95" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="HighlightCloseButton">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="ImgClose"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0.4" />
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="FadeCloseButton">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="ImgClose"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="1" />
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0.4" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="FadeBack">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Grid"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="1" />
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="FadeOut" Completed="OnFadeOutCompleted">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Grid"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="1" />
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0.2" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
<UserControl.Triggers>
<EventTrigger RoutedEvent="tb:TaskbarIcon.BalloonShowing">
<BeginStoryboard Storyboard="{StaticResource FadeIn}" x:Name="FadeInBeginStoryboard" />
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseEnter" SourceName="ImgClose">
<BeginStoryboard Storyboard="{StaticResource HighlightCloseButton}" x:Name="HighlightCloseButtonBeginStoryboard" />
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave" SourceName="ImgClose">
<BeginStoryboard Storyboard="{StaticResource FadeCloseButton}" x:Name="FadeCloseButtonBeginStoryboard" />
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<StopStoryboard BeginStoryboardName="FadeInBeginStoryboard" />
<BeginStoryboard x:Name="FadeBackBeginStoryboard1" Storyboard="{StaticResource FadeBack}" />
</EventTrigger>
<EventTrigger RoutedEvent="tb:TaskbarIcon.BalloonClosing">
<BeginStoryboard Storyboard="{StaticResource FadeOut}" x:Name="FadeOutBeginStoryboard" />
</EventTrigger>
</UserControl.Triggers>
<Grid x:Name="Grid" MouseEnter="Grid_OnMouseEnter" MouseLeave="Grid_OnMouseLeave">
<Border x:Name="BnBorder" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderThickness="1" CornerRadius="5"
BorderBrush="{DynamicResource GridView_FilteringControlOuterBorder}"
Background="{DynamicResource GridView_FilteringControlBackground}">
<Border.Effect>
<DropShadowEffect Color="#FF747474" />
</Border.Effect>
</Border>
<Image HorizontalAlignment="Left" Margin="10 10 0 0" Width="64" Height="64" Stretch="Fill" VerticalAlignment="Top"
Source="{Binding ImageSource}" />
<TextBlock Margin="84 35 10 0" VerticalAlignment="Top" FontSize="16" FontWeight="Bold" Foreground="#FF575757">
<Run Text="VHI Notification"/>
</TextBlock>
<Path Fill="#FFFFFFFF" Stretch="Fill" Margin="84 60 10 0" VerticalAlignment="Top" Height="1"
Data="M26,107 L220.04123,107" SnapsToDevicePixels="True">
<Path.Stroke>
<LinearGradientBrush EndPoint="0.973,0.5" StartPoint="0.005,0.5">
<GradientStop Color="#FF6868FF" Offset="0" />
<GradientStop Color="#346868FF" Offset="1" />
</LinearGradientBrush>
</Path.Stroke>
</Path>
<TextBlock Margin="20 90 10 0" VerticalAlignment="Top" Height="24" TextWrapping="Wrap" FontSize="12" FontWeight="Bold">
<Run Text="⦁ "/>
<Run Text="{Binding NotificationText}"/>
</TextBlock>
<Image x:Name="ImgClose" HorizontalAlignment="Right" Margin="0 10 10 0" VerticalAlignment="Top" Width="16" Height="16"
Stretch="Fill" Opacity="0.4" ToolTip="Close Balloon" Source="pack://application:,,,/Resources/Img/Exit32.png"
MouseDown="ImgClose_OnMouseDown" />
</Grid>
</UserControl>
TrayBalloon.xaml.cs:
public partial class TrayBalloon : UserControl, INotifyPropertyChanged
{
private bool isClosing;
public TrayBalloon()
{
InitializeComponent();
DataContext = this;
TaskbarIcon.AddBalloonClosingHandler(this, OnBalloonClosing);
}
private string imageSource;
public string ImageSource
{
get { return imageSource; }
set
{
imageSource = value;
OnPropertyChanged("ImageSource");
}
}
private string notificationText;
public string NotificationText
{
get { return notificationText; }
set
{
notificationText = value;
OnPropertyChanged("NotificationText");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private void OnBalloonClosing(object sender, RoutedEventArgs e)
{
e.Handled = true;
isClosing = true;
}
private void OnFadeOutCompleted(object sender, EventArgs e)
{
var pp = (Popup)Parent;
pp.IsOpen = false;
}
private void Grid_OnMouseEnter(object sender, MouseEventArgs e)
{
if (isClosing) return;
var taskbarIcon = TaskbarIcon.GetParentTaskbarIcon(this);
taskbarIcon.ResetBalloonCloseTimer();
}
private void Grid_OnMouseLeave(object sender, MouseEventArgs e)
{
if (isClosing) return;
var taskbarIcon = TaskbarIcon.GetParentTaskbarIcon(this);
taskbarIcon.CloseBalloon();
}
private void ImgClose_OnMouseDown(object sender, MouseButtonEventArgs e)
{
var taskbarIcon = TaskbarIcon.GetParentTaskbarIcon(this);
taskbarIcon.CloseBalloon();
}
}
I'm not sure if this is the preferred way to accomplish this in a ViewModel but this is how I got a reference to the TaskbarIcon.
tb = (TaskbarIcon)Application.Current.FindResource("MyTray");
Given:
<ScrollViewer VerticalScrollBarVisibility="Auto" >
<ItemsControl ItemsSource="{Binding Controls}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
Where the "Controls binding" is an ObservableCollection in the viewmodel containing some sort of usercontrols.
As the content in the wrappanel is centered, the current behavior is as follows:
UC A is added to the list, and displayed in the center of the panel.
UC B is added to the list, UC A is moved to the left and UC B is added to the panel.
UC C is added to the list, UC A and B
is moved to the left and UC C is added to the panel.
What I want is to add a "movement" translation/transition when a new usercontrol is added, i.e. I want to show animate the transition of A/B..n the left as each UC is added.
I would prefer to do as much as possible in XAML, and not break the MVVM pattern.
Bonus, I want to be able animate when an UC is removed too.
I consider Controls as an ObservableCollection of FrameworkElement
You can use this code:
<Window x:Class="Marathonbet.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Loaded="MainWindow_OnLoaded" Title="MainWindow" Height="350" Width="525"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Window.Resources>
<Storyboard x:Key="OnLoaded1">
<ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)" >
<EasingThicknessKeyFrame KeyTime="0" Value="20,0,0,0"/>
<EasingThicknessKeyFrame KeyTime="0:0:0.4" Value="5"/>
</ThicknessAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Width)" >
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="55"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" >
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.8" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="OnUnloaded1" >
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)">
<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Width)">
<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="55"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ScrollViewer VerticalScrollBarVisibility="Auto" Grid.Row="0">
<ItemsControl ItemsSource="{Binding Controls}" x:Name="x">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel HorizontalAlignment="Center"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
<Button Grid.Row="1" Content="Add" Margin="5" HorizontalAlignment="Left" Padding="15,2,15,2" Click="btAdd_OnClick"/>
<Button Grid.Row="1" Content="Remove" Margin="64,5,0,5" HorizontalAlignment="Left" Padding="15,2,15,2" Click="btRemove_OnClick"/>
</Grid>
</Window>
Code behind
public class MyObservableCollection : ObservableCollection<FrameworkElement>
{
private Storyboard unloadedStoryboard;
public Storyboard UnloadedSotryBoard
{
get { return unloadedStoryboard; }
set
{
unloadedStoryboard = value;
unloadedStoryboard.Completed += UnloadedStoryboardOnCompleted;
}
}
public Storyboard LoadedSotryBoard { get; set; }
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
foreach (FrameworkElement item in e.NewItems)
item.BeginStoryboard(LoadedSotryBoard);
}
base.OnCollectionChanged(e);
}
private HashSet<int> indexesToRemove = new HashSet<int>();
protected override void RemoveItem(int index)
{
indexesToRemove.Add(index);
var item = Items[index];
UnloadedSotryBoard.Begin(item);
}
private void UnloadedStoryboardOnCompleted(object sender, EventArgs eventArgs)
{
foreach (var i in new HashSet<int>(indexesToRemove))
{
base.RemoveItem(i);
indexesToRemove.Remove(i);
}
}
}
public partial class MainWindow
{
public MyObservableCollection Controls { get; set; }
#region Constructors
public MainWindow()
{
Controls = new MyObservableCollection();
InitializeComponent();
Controls.LoadedSotryBoard = (Storyboard) FindResource("OnLoaded1");
Controls.UnloadedSotryBoard = (Storyboard) FindResource("OnUnloaded1");
}
#endregion
#region Events
private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
{
Controls.Add(new MyControl {DataContext = "A"});
Controls.Add(new MyControl {DataContext = "B"});
Controls.Add(new MyControl {DataContext = "C"});
}
private void btAdd_OnClick(object sender, RoutedEventArgs e)
{
Controls.Add(new MyControl {DataContext = (char) new Random().Next(0, Byte.MaxValue)});
}
private void btRemove_OnClick(object sender, RoutedEventArgs e)
{
if (Controls.Count == 0)
return;
Controls.RemoveAt(Controls.Count - 1);
}
#endregion
}
I am a beginner in WPF.
I want to display my form on every tick.
but it's only displaying once.
when I debug this, it's hitting the this.topmost=true in timer tick event, but
it is not displaying the window.
I am not sure what's wrong with this code.
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer();
timer.Interval = new TimeSpan(0, 0, 0, 2, 0);
timer.Tick += tick;
timer.Start();
}
private void tick(object sender, EventArgs e)
{
this.Topmost = true;//display the form
this.Show();
}
}
<Border BorderThickness="1" Background="Beige" BorderBrush="Black" CornerRadius="10">
<StackPanel Margin="20">
<CheckBox Content="Checkable" Margin="5 5 0 5" />
<Button Content="Clickable" HorizontalAlignment="Center" />
</StackPanel>
</Border>
<!-- Animation -->
<Grid.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)">
<SplineDoubleKeyFrame KeyTime="0:0:0" Value="0"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.0" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="0:0:2" Value="1"/>
<SplineDoubleKeyFrame KeyTime="0:0:8" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
This should do what you want. I have taken the WPF window that you wanted to show to your client and moved it into another form. I then created another startup form that is hidden and runs the timer showing your animation periodically.
Startup Form:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="10" Width="10" ShowInTaskbar="False" Visibility="Hidden" >
<Grid />
</Window>
Startup Form Code Behind
public partial class MainWindow : Window
{
Window1 cyclicWindow;
public MainWindow()
{
InitializeComponent();
cyclicWindow = new Window1();
cyclicWindow.Show();
cyclicWindow.Topmost = true;
System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer();
timer.Interval = new TimeSpan(0, 0, 0, 20, 0);
timer.Tick += tick;
timer.Start();
}
private void tick(object sender, EventArgs e)
{
if (cyclicWindow != null)
{
cyclicWindow.Close() ;
}
cyclicWindow = new Window1();
cyclicWindow.Show();
cyclicWindow.Topmost = true;
}
}
Cycling Window:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="200" Width="300" Name="Main"
ShowInTaskbar="False" WindowStyle="None" Background="Transparent" >
<Grid Name="Base" Height="112">
<Border BorderThickness="1" Background="Beige" BorderBrush="Black" CornerRadius="10">
<StackPanel Margin="20">
<CheckBox Content="Checkable" Margin="5 5 0 5" />
<Button Content="Clickable" HorizontalAlignment="Center" />
</StackPanel>
</Border>
<!-- Animation -->
<Grid.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="Main" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)">
<SplineDoubleKeyFrame KeyTime="0:0:0" Value="0"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.0" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="Main" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="0:0:2" Value="1"/>
<SplineDoubleKeyFrame KeyTime="0:0:8" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
</Grid>
</Window>
Cycling Window Code Behind:
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
AllowsTransparency = true;
}
}
i will post my source code i have at the moment and explain my problem after that.
this is the window where i want the transition to happen
<Window x:Class="MyApp.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MyApp" Height="600" Width="800">
<StackPanel>
<Button Content="View1" Command="{Binding View1Command}"/>
<Button COntent="View2" Command="{Binding View2Command}"/>
<ContentControl Content="{Binding MyContent}"/>
</StackPanel>
This is the associated View-Model
public class MainViewModel
{
public RelayCommand View1Command{ get; private set;}
public RelayCommand View2Command{ get; private set;}
//INotifyPropertyChanged is implemented of course
public ViewModelBase MyContent { get; set;}
public MainViewModel()
{
View1Command = new RelayCommand(() => { MyContent = new ViewModel1();});
View2Command = new RelayCommand(() => { MyContent = new ViewModel2();});
}
}
In the app.xaml i used a data template to associate ViewModel1 with View1 and ViewModel2 with View2. That all works as expected. When clicking the buttons, the view changes, databinding works and everything is ok.
What i like to do now is to use an animation when the view changes.
what do i have to do to animate the transition between the two views with let's say a fade in animation for the new view. the old view disappears and the new one is faded in within one second.
hope you can help me.
best regards
pascal
p.s. if my approach with the data template does not make sense and animation is impossible with that approach i am open for other best practices to change from onw view to another. the solution i use is taken from the wpf demo app by karl shifflet, but i have no idea if that's the right solution for the thing i try to do.
<Window.Resources>
<Storyboard x:Key="OnClick1">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="CC1">
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="CC2">
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="OnClick2">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="CC1">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="CC2">
<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="ButtonBase.Click" SourceName="button">
<BeginStoryboard x:Name="OnClick1_BeginStoryboard" Storyboard="{StaticResource OnClick1}"/>
<BeginStoryboard x:Name="OnClick2_BeginStoryboard" Storyboard="{StaticResource OnClick2}"/>
</EventTrigger>
</Window.Triggers>
<StackPanel>
<Button x:Name="button" Content="View1" Command="{Binding View1Command}"/>
<Button Content="View2" Command="{Binding View2Command}"/>
<Grid>
<ContentControl Name="CC1" Opacity="1" Content="{Binding MyContent}"/>
<ContentControl Name="CC2" Opacity="0" Content="{Binding MyContent}"/>
</Grid>
</StackPanel>
i changed my approach for the transition by using the view model locator for binding view to viewmodel and the visual state manager for transition.
I've made a simple storyboard that takes a particular ListBoxItem and lets it grow by a factor of 1.3. I'd like to add this animation to every ListBoxItem I create dynamically so that it can be activated when it gets a mouse-over, but the storyboard seems to be hardcoded to that first item:
<Storyboard x:Name="ListItem_MouseEntered">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="RecentNews" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="1.3"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="RecentNews" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="1.3"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
How should I go about duplicating this storyboard and setting the target to every listboxitem?
Cheers
Nik
PS, I believe I have some errors in the animation, don't worry about that, it's not part of my question :-)
You can define a ControlTemplate for ListBoxItem in the Resources section of the UserControl like this:
<ControlTemplate x:Key="LIT" TargetType="ListBoxItem">
<Border x:Name="MainBorder" BorderBrush="Red" BorderThickness="2" Background="Yellow" MouseEnter="Border_MouseEnter">
<Border.Resources>
<Storyboard x:Name="ItemStory">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="ItemTransform" Storyboard.TargetProperty="ScaleX">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="1.3"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="ItemTransform" Storyboard.TargetProperty="ScaleY">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="1.3"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Border.Resources>
<Border.RenderTransform>
<ScaleTransform x:Name="ItemTransform" />
</Border.RenderTransform>
<TextBlock Text="{TemplateBinding Content}" />
</Border>
</ControlTemplate>
Handle the MouseEnter event:
private void Border_MouseEnter(object sender, MouseEventArgs e)
{
Border itemBorder = (Border)sender;
Storyboard itemStory = (Storyboard)itemBorder.FindName("ItemStory");
itemStory.Begin();
}
And use it like this in XAML:
<ListBox x:Name="MyList">
<ListBox.Items>
<ListBoxItem Content="Toto 1" Template="{StaticResource LIT}" />
</ListBox.Items>
</ListBox>
Or like this in C#:
MyList.Items.Add(new ListBoxItem()
{
Content="Toto 2",
Template = (ControlTemplate)Resources["LIT"]
});
If you use the visual state manager, you can apply this to all of type:
This shows how to do just that.