WPF,C# 我不明白,Ticker 从 "From" 移动到 "To"
WPF,C# I don't understand, Ticker Moving From "From" to"To"
在代码中
private void TickerGrid_Loaded(object sender, RoutedEventArgs e)
{
double height = TickerCanvas.ActualHeight - TextBoxMarquee.ActualHeight;
TextBoxMarquee.Margin = new Thickness(0, height / 2, 0, 0);
DoubleAnimation doubleAnimation = new DoubleAnimation();
doubleAnimation.From = -TextBoxMarquee.ActualWidth; // -277
doubleAnimation.To = TickerCanvas.ActualWidth; //524
doubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
doubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(5));
TextBoxMarquee.BeginAnimation(Canvas.RightProperty, doubleAnimation);
}
在Xaml
<Grid x:Name="TickerGrid" Grid.Row="2" Loaded="TickerGrid_Loaded" Background="#2B2F3B" >
<Canvas ClipToBounds="True" Name="TickerCanvas" Background="Transparent">
<TextBlock ClipToBounds="True" Name="TextBoxMarquee" Background="#2B2F3B">
<TextBlock.Inlines>
<Run FontWeight="Bold" Foreground="#55CFE3" FontSize="14" Text="This is WPF Ticker Title." />
<Run FontSize="13" Foreground="#FFFFFF" Text="This is Content text." />
</TextBlock.Inlines>
</TextBlock>
</Canvas>
</Grid>
我做了一个行情,但是我不明白Canvas从"From"移动到"To"的原理。
如果这应该是选取框动画,那么我会使用两个文本块。
您将在此处找到文章链接的工作示例:
https://gallery.technet.microsoft.com/WPF-User-Notification-MVVM-98940828
样本有一个网格,它会扩展以适应它所在容器的宽度。
这里面有个canvas
如果内容超出 canvas 范围,Canvas 不会剪辑它的内容。
canvas 允许将一个文本块放置在面板右侧和面板左侧的屏幕外。
然后网格从左到右动画化。
故事板:
<Window.Resources>
<!-- "To" of this is set in code because of the window resizing -->
<Storyboard x:Key="SBmarquee">
<DoubleAnimation From="0"
Duration="00:00:8"
Storyboard.TargetProperty="X"
Storyboard.TargetName="Xmarquee"
RepeatBehavior="3"/>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
Storyboard.TargetName="MarqueeContainer"
To="1"/>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
Storyboard.TargetName="MarqueeContainer"
BeginTime="0:0:20"
Duration="0:0:4" To="0"/>
</Storyboard>
</Window.Resources>
网格:
<Grid x:Name="MarqueeContainer" VerticalAlignment="Bottom">
<Grid.RenderTransform>
<TranslateTransform x:Name="Xmarquee" X="0"/>
</Grid.RenderTransform>
<Canvas Height="24"
TextBlock.Foreground="Red">
<TextBlock Text="{Binding MarqueeMessage, NotifyOnTargetUpdated=True}" Canvas.Left="0">
<TextBlock.Triggers>
<EventTrigger RoutedEvent="Binding.TargetUpdated">
<BeginStoryboard Storyboard="{StaticResource SBmarquee}" />
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>
<TextBlock Text="{Binding MarqueeMessage}"
Foreground="Red"
Canvas.Left="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type Canvas}}}"/>
</Canvas>
</Grid>
随着最左边的文本块移出显示屏,最右边的文本块出现。
Window_ContentRendered和Window_SizeChanged中的代码用于计算window的当前宽度。
private Storyboard SBMarquee;
private DoubleAnimation XAnimation;
private void Window_ContentRendered(object sender, EventArgs e)
{
SBMarquee = this.Resources["SBmarquee"] as Storyboard;
XAnimation = SBMarquee.Children[0] as DoubleAnimation;
XAnimation.To = MarqueeContainer.ActualWidth * -1;
this.SizeChanged += Window_SizeChanged;
}
private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
XAnimation.To = MarqueeContainer.ActualWidth * -1;
MarqueeContainer.Visibility = Visibility.Hidden;
SBMarquee.Begin();
MarqueeContainer.Visibility = Visibility.Visible;
}
动画停止并通过告诉它重新开始重新开始。这是在用户调整大小时避免异常的最简单方法。
我希望你明白了。
TextBoxMarquee.BeginAnimation(Canvas.RightProperty, doubleAnimation);
是令人困惑的部分。
它不会为 Canvas 设置动画。它为文本块的右侧 属性 设置动画。
Canvas.RightProperty 只是 属性 的标识符,而不是对具有 属性 的对象的引用。对 BeginAnimation 的调用是在 TextBoxMarquee 上进行的,因此将对 TextBox 的右侧 属性 进行动画处理。
在代码中
private void TickerGrid_Loaded(object sender, RoutedEventArgs e)
{
double height = TickerCanvas.ActualHeight - TextBoxMarquee.ActualHeight;
TextBoxMarquee.Margin = new Thickness(0, height / 2, 0, 0);
DoubleAnimation doubleAnimation = new DoubleAnimation();
doubleAnimation.From = -TextBoxMarquee.ActualWidth; // -277
doubleAnimation.To = TickerCanvas.ActualWidth; //524
doubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
doubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(5));
TextBoxMarquee.BeginAnimation(Canvas.RightProperty, doubleAnimation);
}
在Xaml
<Grid x:Name="TickerGrid" Grid.Row="2" Loaded="TickerGrid_Loaded" Background="#2B2F3B" >
<Canvas ClipToBounds="True" Name="TickerCanvas" Background="Transparent">
<TextBlock ClipToBounds="True" Name="TextBoxMarquee" Background="#2B2F3B">
<TextBlock.Inlines>
<Run FontWeight="Bold" Foreground="#55CFE3" FontSize="14" Text="This is WPF Ticker Title." />
<Run FontSize="13" Foreground="#FFFFFF" Text="This is Content text." />
</TextBlock.Inlines>
</TextBlock>
</Canvas>
</Grid>
我做了一个行情,但是我不明白Canvas从"From"移动到"To"的原理。
如果这应该是选取框动画,那么我会使用两个文本块。
您将在此处找到文章链接的工作示例:
https://gallery.technet.microsoft.com/WPF-User-Notification-MVVM-98940828
样本有一个网格,它会扩展以适应它所在容器的宽度。
这里面有个canvas
如果内容超出 canvas 范围,Canvas 不会剪辑它的内容。
canvas 允许将一个文本块放置在面板右侧和面板左侧的屏幕外。
然后网格从左到右动画化。
故事板:
<Window.Resources>
<!-- "To" of this is set in code because of the window resizing -->
<Storyboard x:Key="SBmarquee">
<DoubleAnimation From="0"
Duration="00:00:8"
Storyboard.TargetProperty="X"
Storyboard.TargetName="Xmarquee"
RepeatBehavior="3"/>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
Storyboard.TargetName="MarqueeContainer"
To="1"/>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
Storyboard.TargetName="MarqueeContainer"
BeginTime="0:0:20"
Duration="0:0:4" To="0"/>
</Storyboard>
</Window.Resources>
网格:
<Grid x:Name="MarqueeContainer" VerticalAlignment="Bottom">
<Grid.RenderTransform>
<TranslateTransform x:Name="Xmarquee" X="0"/>
</Grid.RenderTransform>
<Canvas Height="24"
TextBlock.Foreground="Red">
<TextBlock Text="{Binding MarqueeMessage, NotifyOnTargetUpdated=True}" Canvas.Left="0">
<TextBlock.Triggers>
<EventTrigger RoutedEvent="Binding.TargetUpdated">
<BeginStoryboard Storyboard="{StaticResource SBmarquee}" />
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>
<TextBlock Text="{Binding MarqueeMessage}"
Foreground="Red"
Canvas.Left="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type Canvas}}}"/>
</Canvas>
</Grid>
随着最左边的文本块移出显示屏,最右边的文本块出现。
Window_ContentRendered和Window_SizeChanged中的代码用于计算window的当前宽度。
private Storyboard SBMarquee;
private DoubleAnimation XAnimation;
private void Window_ContentRendered(object sender, EventArgs e)
{
SBMarquee = this.Resources["SBmarquee"] as Storyboard;
XAnimation = SBMarquee.Children[0] as DoubleAnimation;
XAnimation.To = MarqueeContainer.ActualWidth * -1;
this.SizeChanged += Window_SizeChanged;
}
private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
XAnimation.To = MarqueeContainer.ActualWidth * -1;
MarqueeContainer.Visibility = Visibility.Hidden;
SBMarquee.Begin();
MarqueeContainer.Visibility = Visibility.Visible;
}
动画停止并通过告诉它重新开始重新开始。这是在用户调整大小时避免异常的最简单方法。
我希望你明白了。
TextBoxMarquee.BeginAnimation(Canvas.RightProperty, doubleAnimation);
是令人困惑的部分。
它不会为 Canvas 设置动画。它为文本块的右侧 属性 设置动画。
Canvas.RightProperty 只是 属性 的标识符,而不是对具有 属性 的对象的引用。对 BeginAnimation 的调用是在 TextBoxMarquee 上进行的,因此将对 TextBox 的右侧 属性 进行动画处理。