Quantcast
Channel: Windows Presentation Foundation (WPF) forum
Viewing all articles
Browse latest Browse all 18858

Get time elapsed from storyboard

$
0
0

How to get the time elapsed from storyboard ? The time elapsed needs to display according to the rectangle fill.

MainWindow.xaml

<Window
        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"
        xmlns:local="clr-namespace:wpf_ItemsControl_Wrapped"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        x:Class="wpf_ItemsControl_Wrapped.MainWindow"
        mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"><Window.Resources><local:BorderClipConverter x:Key="BClipConverter"/></Window.Resources><Grid><Grid.Resources><Style TargetType="{x:Type Button}"><Setter Property="Margin" Value="4"/></Style></Grid.Resources><Grid.RowDefinitions><RowDefinition Height="Auto" /><RowDefinition Height="Auto" /><RowDefinition Height="Auto" /><RowDefinition Height="*"/></Grid.RowDefinitions><StackPanel Orientation="Horizontal" Grid.Row="1" Margin="4, 8, 4, 8"><TextBlock Text="Current Value:" VerticalAlignment="Center" /><TextBlock Text="{Binding CurrentValue}" Margin="15, 0, 0, 0" VerticalAlignment="Center" /></StackPanel><StackPanel Orientation="Horizontal" Grid.Row="2" Margin="4, 8, 4, 8"><TextBlock Text="Time Elapsed: " VerticalAlignment="Center" /><!--TBC--><!--<TextBlock Text="x" VerticalAlignment="Center" />--></StackPanel><ListBox x:Name="lb"
            Grid.Row="3" Grid.IsSharedSizeScope="True" AlternationCount="10000" ItemsSource="{Binding Models}" ScrollViewer.HorizontalScrollBarVisibility="Disabled"><ListBox.ItemContainerStyle><Style TargetType="{x:Type ListBoxItem}"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type ListBoxItem}"><ContentPresenter/></ControlTemplate></Setter.Value></Setter></Style></ListBox.ItemContainerStyle><ListBox.ItemsPanel><ItemsPanelTemplate><WrapPanel Orientation="Horizontal" Margin="15, 0, 15, 0" /></ItemsPanelTemplate></ListBox.ItemsPanel><ListBox.ItemTemplate><DataTemplate><Grid><Grid.RowDefinitions><RowDefinition Height="Auto" /><RowDefinition Height="50" /></Grid.RowDefinitions><Grid.ColumnDefinitions><ColumnDefinition MinWidth="150" SharedSizeGroup="AllSameWidth" /></Grid.ColumnDefinitions><Grid><Border
                                BorderThickness="1" BorderBrush="Gray" Height="50"><Border.Clip><MultiBinding Converter="{StaticResource BClipConverter}"><Binding Path="ActualWidth"  RelativeSource="{RelativeSource Self}"/><Binding Path="ActualHeight" RelativeSource="{RelativeSource Self}"/><Binding Path="CornerRadius" RelativeSource="{RelativeSource Self}"/></MultiBinding></Border.Clip><!--<Border.Effect><DropShadowEffect /></Border.Effect>--><Border.Style><Style TargetType="{x:Type Border}"><Style.Triggers><DataTrigger Binding="{Binding (ItemsControl.AlternationIndex), RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" Value="0"><Setter Property="CornerRadius" Value="10, 0, 0, 10" /></DataTrigger><DataTrigger Binding="{Binding IsLastItem, ElementName=lastInLine}"
												Value="true"  ><Setter Property="CornerRadius" Value="0, 10, 10, 0" /></DataTrigger><DataTrigger Binding="{Binding Items.Count, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}" Value="1"><Setter Property="CornerRadius" Value="10, 10, 10, 10" /></DataTrigger></Style.Triggers></Style></Border.Style><local:ItemTracer Width="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}}"
                                              Container="{Binding ., RelativeSource={RelativeSource AncestorType={x:Type WrapPanel}}}"
                                              ContainerWidth="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type WrapPanel}}}"
                                              ItemIndex="{Binding (ItemsControl.AlternationIndex), RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"
                                              ItemsCount="{Binding Items.Count, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}"
                                              x:Name="lastInLine" /></Border><Border
                                Name="TopBorder"
                                BorderThickness="1" BorderBrush="Gray" Height="50"><Border.Style><Style TargetType="{x:Type Border}"><Style.Triggers><DataTrigger Binding="{Binding (ItemsControl.AlternationIndex), RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" Value="0"><Setter Property="CornerRadius" Value="10, 0, 0, 10" /></DataTrigger><DataTrigger Binding="{Binding IsLastItem, ElementName=lastInLine}"
												Value="true"  ><Setter Property="CornerRadius" Value="0, 10, 10, 0" /></DataTrigger><DataTrigger Binding="{Binding Items.Count, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}" Value="1"><Setter Property="CornerRadius" Value="10, 10, 10, 10" /></DataTrigger></Style.Triggers></Style></Border.Style></Border><TextBlock Text="{Binding CurrentValue}" VerticalAlignment="Center" HorizontalAlignment="Center" /></Grid><TextBlock Text="{Binding StartTime, StringFormat=\{0:mm\\:ss\}}" Grid.Row="1" Margin="-14, 0, 0, 0" /><TextBlock Text="{Binding EndTime, StringFormat=\{0:mm\\:ss\}}"  Grid.Row="1" HorizontalAlignment="Right"><TextBlock.RenderTransform><TranslateTransform X="14" Y="0" /></TextBlock.RenderTransform><TextBlock.Style><Style TargetType="{x:Type TextBlock}"><Setter Property="Visibility" Value="Visible"/><Style.Triggers><MultiDataTrigger><MultiDataTrigger.Conditions><Condition Binding="{Binding IsLastInLine, ElementName=lastInLine}" Value="False" /><Condition Binding="{Binding IsLastItem, ElementName=lastInLine}" Value="False" /></MultiDataTrigger.Conditions><Setter Property="Visibility" Value="Collapsed" /></MultiDataTrigger></Style.Triggers></Style></TextBlock.Style></TextBlock></Grid></DataTemplate></ListBox.ItemTemplate></ListBox></Grid></Window>

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace wpf_ItemsControl_Wrapped
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private MainWindowViewModel mainWindowViewModel;

        public MainWindow()
        {
            InitializeComponent();
            mainWindowViewModel = new MainWindowViewModel();
            DataContext = mainWindowViewModel;
            ContentRendered += MainWindow_ContentRendered;
        }

        private void MainWindow_ContentRendered(object sender, EventArgs e)
        {
            IList<ItemTracer> itemTracers = new List<ItemTracer>();

            foreach (Model model in lb.Items)
            {
                ListBoxItem lbi = lb.ItemContainerGenerator.ContainerFromItem(model) as ListBoxItem;
                ItemTracer tracer = FindVisualChild<ItemTracer>(lbi);
                itemTracers.Add(tracer);
            }

            mainWindowViewModel.ItemTracers = new ReadOnlyCollection<ItemTracer>(itemTracers);
            mainWindowViewModel.Start();
        }

        private childItem FindVisualChild<childItem>(DependencyObject obj) where childItem : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(obj, i);

                if (child is childItem)
                {
                    return (childItem)child;
                }
                else
                {
                    childItem childOfChild = FindVisualChild<childItem>(child);

                    if (childOfChild != null)
                    {
                        return childOfChild;
                    }
                }
            }

            return null;
        }
    }
}

MainWindowViewModel.cs

using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Media.Animation;

namespace wpf_ItemsControl_Wrapped
{
    public class MainWindowViewModel : ViewModelBase
    {
        private ObservableCollection<Model> models;

        public ObservableCollection<Model> Models
        {
            get
            {
                if (models == null)
                {
                    models = new ObservableCollection<Model>();
                }
                return models;
            }
        }

        private TimeSpan stepTime = TimeSpan.FromSeconds(15);

        public TimeSpan StepTime
        {
            get { return stepTime; }
            set
            {
                stepTime = value;
            }
        }

        private ReadOnlyCollection<ItemTracer> itemTracers;

        public ReadOnlyCollection<ItemTracer> ItemTracers
        {
            get { return itemTracers; }
            set
            {
                itemTracers = value;
            }
        }

        private string currentValue;

        public string CurrentValue
        {
            get { return currentValue; }
            set
            {
                currentValue = value;
                OnPropertyChanged("CurrentValue");
            }
        }

        private int currentValueCount = 0;

        public MainWindowViewModel()
        {
            Random rand = new Random();
            Models.Add(new Model { StartTime = LastEnd(), Duration = TimeSpan.FromSeconds(10), CurrentValue = rand.Next() });
            Models.Add(new Model { StartTime = LastEnd(), Duration = TimeSpan.FromSeconds(20), CurrentValue = rand.Next() });
            Models.Add(new Model { StartTime = LastEnd(), Duration = TimeSpan.FromSeconds(30), CurrentValue = rand.Next() });
            Models.Add(new Model { StartTime = LastEnd(), Duration = TimeSpan.FromSeconds(40), CurrentValue = rand.Next() });
            Models.Add(new Model { StartTime = LastEnd(), Duration = TimeSpan.FromSeconds(50), CurrentValue = rand.Next() });
            Models.Add(new Model { StartTime = LastEnd(), Duration = TimeSpan.FromSeconds(60), CurrentValue = rand.Next() });
        }

        public void Start()
        {
            for (int i = 0; i < itemTracers.Count(); i++)
            {
                Storyboard itemTracerStoryboard = itemTracers[i].progressRectangle.Resources["sb"] as Storyboard;
                itemTracerStoryboard.Completed += ItemTracerStoryboard_Completed;
                itemTracerStoryboard.Begin();
            }

            UpdateCurrentValue();
        }

        private void ItemTracerStoryboard_Completed(object sender, EventArgs e)
        {
            UpdateCurrentValue();
        }

        public TimeSpan LastEnd()
        {
            return (Models.Count == 0) ? TimeSpan.FromSeconds(0) : Models.Last<Model>().EndTime;
        }

        private void UpdateCurrentValue()
        {
            CurrentValue = Models[currentValueCount].CurrentValue.ToString();

            if (currentValueCount != Models.Count() - 1)
            {
                currentValueCount++;
            }
        }
    }
}


ItemTracer.xaml

<UserControl x:Class="wpf_ItemsControl_Wrapped.ItemTracer"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:wpf_ItemsControl_Wrapped"
             mc:Ignorable="d"
             d:DesignHeight="300" d:DesignWidth="300"><Grid><Border
            Name="progressRectangle"
            Height="10" Background="SkyBlue" VerticalAlignment="Bottom"><Border.RenderTransform><ScaleTransform ScaleX="0" ScaleY="1"/></Border.RenderTransform><Border.Resources><Storyboard x:Key="sb"><DoubleAnimation
                       Storyboard.TargetName="progressRectangle"
                       Storyboard.TargetProperty="(Border.RenderTransform).(ScaleTransform.ScaleX)"
                       From="0"
                       To="1"
                       AutoReverse="False"
                       FillBehavior="HoldEnd"
                       BeginTime="{Binding StartTime}"
                       Duration="{Binding DurationStoryboard}"
                          /></Storyboard></Border.Resources></Border></Grid></UserControl>

ItemTracer.xaml.cs

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;

namespace wpf_ItemsControl_Wrapped
{
    public partial class ItemTracer : UserControl
    {
        public ItemTracer()
        {
            InitializeComponent();
            EvaluateIsLastInLine(this);
            EvaluateIsLastItem(this);
        }

        public bool IsLastInLine
        {
            get { return (bool)GetValue(IsLastInLineProperty); }
            set { SetValue(IsLastInLineProperty, value); }
        }

        public static readonly DependencyProperty IsLastInLineProperty = DependencyProperty.Register("IsLastInLine", typeof(bool), typeof(ItemTracer), new PropertyMetadata(false));

        public double ContainerWidth
        {
            get { return (double)GetValue(ContainerWidthProperty); }
            set { SetValue(ContainerWidthProperty, value); }
        }

        public static readonly DependencyProperty ContainerWidthProperty = DependencyProperty.Register("ContainerWidth", typeof(double), typeof(ItemTracer), new PropertyMetadata(0.0, new PropertyChangedCallback(OnContainerWidthChanged)));
        public UIElement Container
        {
            get { return (UIElement)GetValue(ContainerProperty); }
            set { SetValue(ContainerProperty, value); }
        }
        public static readonly DependencyProperty ContainerProperty = DependencyProperty.Register("Container", typeof(UIElement), typeof(ItemTracer));

        public int ItemsCount
        {
            get { return (int)GetValue(ItemsCountProperty); }
            set { SetValue(ItemsCountProperty, value); }
        }

        public static readonly DependencyProperty ItemsCountProperty = DependencyProperty.Register("ItemsCount", typeof(int), typeof(ItemTracer), new PropertyMetadata(0, new PropertyChangedCallback(OnItemsCountChanged)));

        public int ItemIndex
        {
            get { return (int)GetValue(ItemIndexProperty); }
            set { SetValue(ItemIndexProperty, value); }
        }

        public static readonly DependencyProperty ItemIndexProperty = DependencyProperty.Register("ItemIndex", typeof(int), typeof(ItemTracer), new PropertyMetadata(0, new PropertyChangedCallback(OnItemIndexChanged)));

        public bool IsLastItem
        {
            get { return (bool)GetValue(IsLastItemProperty); }
            set { SetValue(IsLastItemProperty, value); }
        }

        public static readonly DependencyProperty IsLastItemProperty = DependencyProperty.Register("IsLastItem", typeof(bool), typeof(ItemTracer), new PropertyMetadata(false));


        private static void OnContainerWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            EvaluateIsLastInLine(d);
        }

        private static void EvaluateIsLastInLine(DependencyObject d)
        {
            bool _isLastInLine = false;
            ItemTracer _this = (ItemTracer)d;
            Point relativeLocation = _this.TranslatePoint(new Point(0, 0), (UIElement)_this.GetValue(ContainerProperty));
            double leftInRow = (double)_this.GetValue(ContainerWidthProperty) - relativeLocation.X;

            if (leftInRow < ((double)_this.GetValue(ActualWidthProperty) * 2))
            {
                _isLastInLine = true;
            }

            _this.SetCurrentValue(IsLastInLineProperty, _isLastInLine);
        }

        private static void OnItemsCountChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            EvaluateIsLastItem(d);
        }

        private static void OnItemIndexChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            EvaluateIsLastItem(d);
        }

        private static void EvaluateIsLastItem(DependencyObject d)
        {
            ItemTracer _this = (ItemTracer)d;
            bool _isLastItem = false;
            //Debug.WriteLine(_this.GetValue(ItemIndexProperty).ToString() + " of " + _this.GetValue(ItemsCountProperty).ToString());

            if ((int)_this.GetValue(ItemsCountProperty) - (int)_this.GetValue(ItemIndexProperty) == 1)
            {
                _isLastItem = true;
            }

            _this.SetCurrentValue(IsLastItemProperty, _isLastItem);
        }
    }
}



Download Project

 

Viewing all articles
Browse latest Browse all 18858

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>