ImageControl с показом ProgressRing для Win 8/RT

в 19:21, , рубрики: windows, Windows RT, Программирование, метки:

Зачем?

В любой Windows 8/RT прилижении требуется отображать определенное количество графики. Ресурсы можно черпать повсеместно: напрямую из Web и постоянно выкачивать файлы; единажды получив файлы работать с ними через IsolatedStorage и так далее. Все хорошо до таго момента, пока загрузка этой графики не начинает занимать продолжнительное время (даже секунда это много). В этот момент требуется визуально «обнадежить» пользователя, и занять пустое место, на котором через мгновение появится изображение. Тут нам на помощь приходит ProgressRing и, естественно, удобнее всего написать один раз контрол и забыть об это надолго.

Идея

Идея действительнобанальна: Border, Image, ProgressRing — больше ничего нам не понадобится.

  • Border : на тот случай, если требуется обвести картинку. Далеко не самый обязательный элемент, но, иногда, очень необходимый.
  • ProgressRing : будет виден в тот момент, когда ImageSource уже назначено, но Image еще не открыт.
  • Image: естественно, самый важный элемент ради которого мы все и затеяли.

Принцип работы

Просто играемся с прозрачностью ProgressRing . Имеем две точки входа: событие ImageOpened (скрываем ProgressRing) и место назначения нового ImageSource(показываемProgressRing).

Код

ProgressImage.xaml

<UserControl
    x:Class="test.Controls.ProgressImage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:test.Controls"
    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">
    <Border x:Name="Border" BorderThickness="1" >
		<Grid>
			<ProgressRing x:Name="Ring" Width="100" Height="100" IsActive="True"  Foreground="#FF6D31F5" />
			<Image x:Name="Image" Margin="0" ImageOpened="Image_OnImageOpened" />
		</Grid>
	</Border>
</UserControl>

ProgressImage.cs

 public sealed partial class ProgressImage : UserControl
    {
        #region Common
        
        public ProgressImage()
        {
            InitializeComponent();
        }

        private void Image_OnImageOpened(object sender, RoutedEventArgs e)
        {
            Ring.Opacity = 0;
        }
        
        #endregion   

        #region Dependency

        private static readonly Color DefRingColor = Colors.BlueViolet;
        private static readonly Color DefBorderColor = Colors.White;
        private static readonly ImageSource DefSource = null;
        private const Stretch DefStretch = Stretch.None;


        /// <summary>
        /// Set Image Source
        /// </summary>
        public ImageSource Source
        {
            get { return (ImageSource)GetValue(SourceProperty); }
            set { SetValue(SourceProperty, value); }
        }

        public static readonly DependencyProperty SourceProperty = DependencyProperty.Register("Source", typeof(ImageSource), typeof(ProgressImage), new PropertyMetadata(DefSource,SourceChanged));

        private static void SourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var controll = (ProgressImage)d;
            var val = (ImageSource)e.NewValue;
            controll.Image.Source = val;
            controll.Ring.Opacity = 100;
        }

        /// <summary>
        /// Set ProgressRing Size
        /// </summary>
        public int ProgressRingSize
        {
            get { return (int)GetValue(ProgressRingSizeProperty); }
            set { SetValue(ProgressRingSizeProperty, value); }
        }

        public static readonly DependencyProperty ProgressRingSizeProperty = DependencyProperty.Register("ProgressRingSize", typeof(int), typeof(ProgressImage),
            new PropertyMetadata(55, ProgressRingSizeChanged));

        private static void ProgressRingSizeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var controll = (ProgressImage)d;
            var val = (int)e.NewValue;
            controll.Ring.Width = val;
            controll.Ring.Height = val;
        }


        /// <summary>
        /// Set ProgressRing Color
        /// </summary>
        public Color ProgressRingColor
        {
            get { return (Color)GetValue(ProgressRingcolorProperty); }
            set { SetValue(ProgressRingcolorProperty, value); }
        }

        public static readonly DependencyProperty ProgressRingcolorProperty = DependencyProperty.Register("ProgressRingColor", typeof(Color), typeof(ProgressImage),
            new PropertyMetadata(DefRingColor, ProgressRingColorChanged));

        private static void ProgressRingColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var controll = (ProgressImage)d;
            var val = (Color)e.NewValue;
            controll.Ring.Foreground = new SolidColorBrush(val);
        }

        /// <summary>
        /// Set Border Color
        /// </summary>
        public Color BorderColor
        {
            get { return (Color)GetValue(BorderColorProperty); }
            set { SetValue(BorderColorProperty, value); }
        }


        public static readonly DependencyProperty BorderColorProperty = DependencyProperty.Register("BorderColor", typeof(Color), typeof(ProgressImage),
            new PropertyMetadata(DefBorderColor, BorderColorChanged));

        private static void BorderColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var controll = (ProgressImage)d;
            var val = (Color)e.NewValue;
            controll.Border.BorderBrush = new SolidColorBrush(val);
        }

        /// <summary>
        /// Set BorderThickness
        /// </summary>
        public double BorderSize
        {
            get { return (double)GetValue(BorderSizeProperty); }
            set { SetValue(BorderSizeProperty, value); }
        }

        public static readonly DependencyProperty BorderSizeProperty = DependencyProperty.Register("BorderSize", typeof(double), typeof(ProgressImage), new PropertyMetadata(0.0, BorderSizeChanged));

        private static void BorderSizeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var controll = (ProgressImage)d;
            var val = (double)e.NewValue;
            controll.Border.BorderThickness = new Thickness(val);
        }

        /// <summary>
        /// Set Border Corner Radius
        /// </summary>
        public int BorderCornerRadius
        {
            get { return (int)GetValue(BorderCornerRadiusProperty); }
            set { SetValue(BorderCornerRadiusProperty, value); }
        }

        public static readonly DependencyProperty BorderCornerRadiusProperty = DependencyProperty.Register("BorderCornerRadius", typeof(int), typeof(ProgressImage), new PropertyMetadata(0, BorderCornerRadiusChanged));

        private static void BorderCornerRadiusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var controll = (ProgressImage)d;
            var val = (int)e.NewValue;
            controll.Border.CornerRadius = new CornerRadius(val);
        }


        /// <summary>
        /// Set Image Stretch
        /// </summary>
        public Stretch ImageStretch
        {
            get { return (Stretch)GetValue(ImageStretchProperty); }
            set { SetValue(ImageStretchProperty, value); }
        }

        public static readonly DependencyProperty ImageStretchProperty = DependencyProperty.Register("ImageStretch", typeof(Stretch), typeof(ProgressImage), new PropertyMetadata(DefStretch, ImageStretchChanged));

        private static void ImageStretchChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var controll = (ProgressImage)d;
            var val = (Stretch)e.NewValue;
            controll.Image.Stretch = val;
        }

        /// <summary>
        /// Set Image Stretch
        /// </summary>
        public double ImageMargin
        {
            get { return (double)GetValue(ImageMarginProperty); }
            set { SetValue(ImageMarginProperty, value); }
        }

        public static readonly DependencyProperty ImageMarginProperty = DependencyProperty.Register("ImageMargin", typeof(double), typeof(ProgressImage), new PropertyMetadata(0.0, ImageMarginChanged));

        private static void ImageMarginChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var controll = (ProgressImage)d;
            var val = (double)e.NewValue;
            controll.Image.Margin = new Thickness(val);
        }

        #endregion

    }

Список насроек ключает в себя (имена говорящие, но все равно стоит пояснить):

  • Source — назначение ImageSource
  • ProgressRingSize — размеры ProgressRing
  • ProgressRingColor — цветProgressRing
  • BorderColor — цветBorder
  • BorderSize — размер BorderThickness
  • BorderCornerRadius — размер радиуса углов Border
  • ImageStretch — говорит само за себя
  • ImageMargin — назначение Margin для Image относительно Border
  • ControlBackground — назначение цвета фона всего контрола

Использывать крайне просто:

Не забывае про:

xmlns:controls="using:test.Controls"

И легко используем:

<controls:ProgressImage x:Name="ProgressImage" Grid.Column="1" Margin="0,0,20,0" Width="300" Height="300" BorderSize="3" BorderColor="White" ProgressRingColor="Red" ImageStretch="None" ProgressRingSize="60" HorizontalAlignment="Right" VerticalAlignment="Center"/>

Что мы получаем?

Наличие под рукой такого контрола — позволяет в любую минуту его подправить под свои конкретные нужны. Основные настройки уже включены, а добавить новые — двухминутное дело. Искренне надеюсь, что кому-нибудь сэкономил время. А вот как выглядет это.
ImageControl с показом ProgressRing для Win 8/RT

Объективная/необъективная критика, а также предложения по улучшению бутут крайне хорошо восприняты.

Автор: jimpanzer

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js