WPF, C# Я не понимаю, тикер переходит от "От" к "К" - PullRequest
0 голосов
/ 03 апреля 2020

в коде

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>

This Ticker Picture

Я сделал тикер, но я не понимаю принципа, что Canvas перемещается от "От" до "До".

Ответы [ 2 ]

1 голос
/ 03 апреля 2020

TextBoxMarquee.BeginAnimation(Canvas.RightProperty, doubleAnimation); запутанная часть.

НЕ оживляет холст. Он анимирует свойство Right текстового блока.

Canvas.RightProperty - это просто идентификатор свойства, а не ссылка на объект, который имеет свойство. Вызов BeginAnimation находится в TextBoxMarquee, поэтому свойство Right в TextBox будет анимированным.

0 голосов
/ 03 апреля 2020

Если предполагается, что это анимация выделения, я бы использовал два текстовых блока.

Вы найдете рабочий образец, связанный со статьей, здесь:

https://social.technet.microsoft.com/wiki/contents/articles/31416.wpf-mvvm-friendly-user-notification.aspx#Marquee

https://gallery.technet.microsoft.com/WPF-User-Notification-MVVM-98940828

В образце есть сетка, которая будет расширяться до ширины любого контейнера, в котором она находится.

Там это холст в этом.

Канва не обрезает свое содержимое, если оно находится за пределами границ холста.

Этот холст позволяет одному текстовому блоку располагаться вне экрана справа от панели, а другой - другому. слева от панели.

Сетка затем анимируется слева направо.

Раскадровка:

<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 используется для вычисления текущей ширины окна.

    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;
    }

Анимация останавливается и перезаписывается - начал с того, чтобы сказать, чтобы начать снова. Это самый простой способ избежать странностей при изменении размера пользователя.

Надеюсь, это понятно.

...