Повторное использование пользовательского элемента управления WPF путем параметризации не работает - PullRequest
0 голосов
/ 23 января 2019

В приложении MVVM у меня есть пользовательский контроль ниже.

Из разных областей моего главного окна WPF я создаю разные экземпляры этого пользовательского элемента управления, поэтому я хотел бы параметризовать этот пользовательский элемент управления, чтобы повторно использовать его и отображать разные сообщения в его метке каждый раз, когда я создаю новый экземпляр этого Для этого я создал свойство зависимостей в коде пользовательского элемента управления с именем MessageText и связал его с меткой в ​​стиле пользовательского элемента управления.

Контроль пользователя :

<UserControl x:Class="My.Apps.WPF.Demo.Controls.UCBusy"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="300" Width="300">

    <UserControl.Resources>
        <Color x:Key="FilledColor" A="255" B="222" R="176" G="196"/>
        <Color x:Key="UnfilledColor" A="0" B="222" R="176" G="196"/>           

        <Style x:Key="BusyAnimationStyle" TargetType="Control">
            <Setter Property="Background" Value="white" />          

            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Control">
                        <ControlTemplate.Resources>
                            <Storyboard x:Key="Animation0" BeginTime="00:00:00.0" RepeatBehavior="Forever">
                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse0" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                    <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                    <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                                </ColorAnimationUsingKeyFrames>
                            </Storyboard>

                            <Storyboard x:Key="Animation1" BeginTime="00:00:00.2" RepeatBehavior="Forever">
                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse1" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                    <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                    <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                                </ColorAnimationUsingKeyFrames>
                            </Storyboard>

                            <Storyboard x:Key="Animation2" BeginTime="00:00:00.4" RepeatBehavior="Forever">
                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse2" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                    <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                    <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                                </ColorAnimationUsingKeyFrames>
                            </Storyboard>

                            <Storyboard x:Key="Animation3" BeginTime="00:00:00.6" RepeatBehavior="Forever">
                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse3" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                    <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                    <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                                </ColorAnimationUsingKeyFrames>
                            </Storyboard>

                            <Storyboard x:Key="Animation4" BeginTime="00:00:00.8" RepeatBehavior="Forever">
                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse4" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                    <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                    <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                                </ColorAnimationUsingKeyFrames>
                            </Storyboard>

                            <Storyboard x:Key="Animation5" BeginTime="00:00:01.0" RepeatBehavior="Forever">
                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse5" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                    <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                    <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                                </ColorAnimationUsingKeyFrames>
                            </Storyboard>

                            <Storyboard x:Key="Animation6" BeginTime="00:00:01.2" RepeatBehavior="Forever">
                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse6" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                    <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                    <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                                </ColorAnimationUsingKeyFrames>
                            </Storyboard>

                            <Storyboard x:Key="Animation7" BeginTime="00:00:01.4" RepeatBehavior="Forever">
                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse7" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                    <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                    <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                                </ColorAnimationUsingKeyFrames>
                            </Storyboard>
                        </ControlTemplate.Resources>

                        <ControlTemplate.Triggers>                            
                            <Trigger Property="IsVisible" Value="True">                                                                

                                <Trigger.EnterActions>                                    
                                    <BeginStoryboard Storyboard="{StaticResource Animation0}" x:Name="Storyboard0" />
                                    <BeginStoryboard Storyboard="{StaticResource Animation1}" x:Name="Storyboard1"/>
                                    <BeginStoryboard Storyboard="{StaticResource Animation2}" x:Name="Storyboard2"/>
                                    <BeginStoryboard Storyboard="{StaticResource Animation3}" x:Name="Storyboard3"/>
                                    <BeginStoryboard Storyboard="{StaticResource Animation4}" x:Name="Storyboard4"/>
                                    <BeginStoryboard Storyboard="{StaticResource Animation5}" x:Name="Storyboard5"/>
                                    <BeginStoryboard Storyboard="{StaticResource Animation6}" x:Name="Storyboard6"/>
                                    <BeginStoryboard Storyboard="{StaticResource Animation7}" x:Name="Storyboard7"/>
                                </Trigger.EnterActions>

                                <Trigger.ExitActions>
                                    <StopStoryboard BeginStoryboardName="Storyboard0"/>
                                    <StopStoryboard BeginStoryboardName="Storyboard1"/>
                                    <StopStoryboard BeginStoryboardName="Storyboard2"/>
                                    <StopStoryboard BeginStoryboardName="Storyboard3"/>
                                    <StopStoryboard BeginStoryboardName="Storyboard4"/>
                                    <StopStoryboard BeginStoryboardName="Storyboard5"/>
                                    <StopStoryboard BeginStoryboardName="Storyboard6"/>
                                    <StopStoryboard BeginStoryboardName="Storyboard7"/>
                                </Trigger.ExitActions>
                            </Trigger>
                        </ControlTemplate.Triggers>

                        <Border BorderBrush="{TemplateBinding BorderBrush}" 
                                BorderThickness="{TemplateBinding BorderThickness}" 
                                Background="{TemplateBinding Background}">

                            <Grid>
                                <Canvas Height="60" Width="60">
                                    <Canvas.Resources>
                                        <Style TargetType="Ellipse">
                                            <Setter Property="Width" Value="15"/>
                                            <Setter Property="Height" Value="15" />
                                            <Setter Property="Fill" Value="#009B9B9B" />
                                        </Style>
                                    </Canvas.Resources>

                                    <Ellipse x:Name="ellipse0" Canvas.Left="1.75" Canvas.Top="21"/>
                                    <Ellipse x:Name="ellipse1" Canvas.Top="7" Canvas.Left="6.5"/>
                                    <Ellipse x:Name="ellipse2" Canvas.Left="20.5" Canvas.Top="0.75"/>
                                    <Ellipse x:Name="ellipse3" Canvas.Left="34.75" Canvas.Top="6.75"/>
                                    <Ellipse x:Name="ellipse4" Canvas.Left="40.5" Canvas.Top="20.75" />
                                    <Ellipse x:Name="ellipse5" Canvas.Left="34.75" Canvas.Top="34.5"/>
                                    <Ellipse x:Name="ellipse6" Canvas.Left="20.75" Canvas.Top="39.75"/>
                                    <Ellipse x:Name="ellipse7" Canvas.Top="34.25" Canvas.Left="7" />
                                    <Ellipse Width="39.5" Height="39.5" Canvas.Left="8.75" Canvas.Top="8" Visibility="Hidden"/> 

                                    <Label Content="{Binding Path=MessageText}" 
                                           FontSize="17"
                                           Canvas.Left="60.5" Canvas.Top="11.5"
                                           HorizontalContentAlignment="Center" 
                                           VerticalAlignment="Center"/>

                                </Canvas>
                            </Grid>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>   

    <Control Style="{StaticResource BusyAnimationStyle}" />

</UserControl>

Код контроля пользователя позади :

    public partial class UCBusy : UserControl
    {
        public UCBusy()
        {
            InitializeComponent();
        }

        public static readonly DependencyProperty MessageTextProperty =
DependencyProperty.Register("MessageText", typeof(string), typeof(UCBusy));
        public string MessageText
        {
            get
            {
                return this.GetValue(MessageTextProperty) as string;
            }
            set
            {
                this.SetValue(MessageTextProperty, value);
            }
        }
    }

Затем в представлении я связываю только что созданное свойство зависимости пользовательского элемента управления со свойствами в модели представления:

Просмотр модели :

<!-- Instance 1 -->
<controls:UCBusy MessageText="{Binding Path=WaitMessageText_1}" />

<!-- Instance 2 -->
<controls:UCBusy MessageText="{Binding Path=WaitMessageText_2}" />

... и с учетом модели ...

Просмотр модели :

            private string _waitMessageText_1 = "Hi there! I am message 1";
            private string _waitMessageText_2 = "Hi there! I am message 2";

            /// <summary>
            ///   Gets or sets the wait message text 1.
            /// </summary>
            public string WaitMessageText_1
            {
                get
                {
                    return _waitMessageText_1;
                }

                set
                {
                    if (_waitMessageText_1 == value) return;
                    _waitMessageText_1 = value;

                    OnPropertyChanged("WaitMessageText_1");
                }
            }

            /// <summary>
            ///   Gets or sets the wait message text 2.
            /// </summary>
            public string WaitMessageText_2
            {
                get
                {
                    return _waitMessageText_2;
                }

                set
                {
                    if (_waitMessageText_2 == value) return;
                    _waitMessageText_2 = value;

                    OnPropertyChanged("WaitMessageText_2");
                }
            }

Наконец, из модели представления я устанавливаю эти свойства, когда это необходимо, но я отмечаю, что мое представление не обновляется новыми сообщениями, которые я помещаю, я имею в виду, метка в пользовательском элементе управления ничего не отображает. Что я делаю неправильно? Я думаю, что-то упустил где-нибудь ...

Примечание. В моем случае Datacontext всегда один и тот же (я установил его для отображения модели), поэтому нет необходимости менять его каждый раз, когда я создаю новый экземпляр пользовательского элемента управления.

1 Ответ

0 голосов
/ 23 января 2019

Я бы попросил вас взглянуть на ранее предоставленный мною ответ, в котором каждый шаг был посвящен настраиваемому элементу управления, свойствам, стилю и т. Д. Это тоже здесь, на S / O

Пара прямых вопросов ... Ваше объявление "Style" основано на "Control", но ваш класс основан на "Control", но ваш пользовательский класс явно является элементом управления "UCBusy", поэтому "Control" понятия не имеет, что такое «MessageText» для привязки стиля.

Кроме того, вы получили это частично, потому что вы объявили другой тип класса.

отредактировано с полным образцом в соответствии с моими предыдущими предложениями. Вот исходный код, который работает, чтобы увидеть все части. Я создал новый проект "StackHelp" и имею следующее. Обратите внимание, что объединенный словарь ссылается на подпапку «component / MyClasses…», где создаются мои пользовательские классы и соответствующие словари ресурсов .xaml.

app.xaml

<Application 
    x:Class="StackHelp.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    StartupUri="MyMainWindow.xaml">

    <Application.Resources>
        <!-- Generic up front for the entire application for the theme / styles to be used -->
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary  Source="pack://application:,,,/StackHelp;component/MyClasses/UCBusy.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

MyClasses \ UCBusy.cs (в подпапке проекта)

using System.Windows;
using System.Windows.Controls;

namespace StackHelp.MyClasses
{
    public class UCBusy : UserControl
    {
        public UCBusy()
        {
            // just to default so style will allow us to see where this will present
            // even just during design time sample.
            MessageText = "My Sample Text";
        }

        public static readonly DependencyProperty MessageTextProperty
            = DependencyProperty.Register("MessageText",
            typeof(string), typeof(UCBusy));
        public string MessageText
        {
            get { return GetValue(MessageTextProperty) as string; }
            set { SetValue(MessageTextProperty, value); }
        }
    }
}

MyClasses \ UCBusy.xaml (xaml - это специально РЕСУРСНЫЙ СЛОВАРЬ) Определены два стиля ... базовый, просто как отдельный ярлык, просто чтобы посмотреть, КАК сделаны привязки ... ВТОРОЙ, специально для того, чтобы сделать ваш сложный стиль. «Xmlns: myC» означает, что псевдоним «myC» относится к классам в подпапке «MyClasses» проекта для каждого пространства имен.

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:myC="clr-namespace:StackHelp.MyClasses">

    <!-- resource dictionary is in-itself a list of resources -->

    <!-- Just a SIMPLE Style to test the proper bindings... as basic as possible to test context working -->
    <Style TargetType="{x:Type myC:UCBusy}" x:Key="BusyAnimationStyleBasic">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type myC:UCBusy}" >
                    <Label Content="{TemplateBinding MessageText}" 
                        FontSize="17"
                        HorizontalContentAlignment="Center" 
                        VerticalAlignment="Center"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>


    <Color x:Key="FilledColor" A="255" B="222" R="176" G="196"/>
    <Color x:Key="UnfilledColor" A="0" B="222" R="176" G="196"/>


    <!-- Now, your elaborate style with all animations...-->
    <Style TargetType="{x:Type myC:UCBusy}" x:Key="BusyAnimationStyle">
        <Setter Property="Background" Value="white" />

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type myC:UCBusy}" >

                    <ControlTemplate.Resources>
                        <Storyboard x:Key="Animation0" BeginTime="00:00:00.0" RepeatBehavior="Forever">
                            <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse0" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                            </ColorAnimationUsingKeyFrames>
                        </Storyboard>

                        <Storyboard x:Key="Animation1" BeginTime="00:00:00.2" RepeatBehavior="Forever">
                            <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse1" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                            </ColorAnimationUsingKeyFrames>
                        </Storyboard>

                        <Storyboard x:Key="Animation2" BeginTime="00:00:00.4" RepeatBehavior="Forever">
                            <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse2" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                            </ColorAnimationUsingKeyFrames>
                        </Storyboard>

                        <Storyboard x:Key="Animation3" BeginTime="00:00:00.6" RepeatBehavior="Forever">
                            <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse3" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                            </ColorAnimationUsingKeyFrames>
                        </Storyboard>

                        <Storyboard x:Key="Animation4" BeginTime="00:00:00.8" RepeatBehavior="Forever">
                            <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse4" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                            </ColorAnimationUsingKeyFrames>
                        </Storyboard>

                        <Storyboard x:Key="Animation5" BeginTime="00:00:01.0" RepeatBehavior="Forever">
                            <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse5" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                            </ColorAnimationUsingKeyFrames>
                        </Storyboard>

                        <Storyboard x:Key="Animation6" BeginTime="00:00:01.2" RepeatBehavior="Forever">
                            <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse6" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                            </ColorAnimationUsingKeyFrames>
                        </Storyboard>

                        <Storyboard x:Key="Animation7" BeginTime="00:00:01.4" RepeatBehavior="Forever">
                            <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse7" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                            </ColorAnimationUsingKeyFrames>
                        </Storyboard>
                    </ControlTemplate.Resources>

                    <ControlTemplate.Triggers>
                        <Trigger Property="IsVisible" Value="True">

                            <Trigger.EnterActions>
                                <BeginStoryboard Storyboard="{StaticResource Animation0}" x:Name="Storyboard0" />
                                <BeginStoryboard Storyboard="{StaticResource Animation1}" x:Name="Storyboard1"/>
                                <BeginStoryboard Storyboard="{StaticResource Animation2}" x:Name="Storyboard2"/>
                                <BeginStoryboard Storyboard="{StaticResource Animation3}" x:Name="Storyboard3"/>
                                <BeginStoryboard Storyboard="{StaticResource Animation4}" x:Name="Storyboard4"/>
                                <BeginStoryboard Storyboard="{StaticResource Animation5}" x:Name="Storyboard5"/>
                                <BeginStoryboard Storyboard="{StaticResource Animation6}" x:Name="Storyboard6"/>
                                <BeginStoryboard Storyboard="{StaticResource Animation7}" x:Name="Storyboard7"/>
                            </Trigger.EnterActions>

                            <Trigger.ExitActions>
                                <StopStoryboard BeginStoryboardName="Storyboard0"/>
                                <StopStoryboard BeginStoryboardName="Storyboard1"/>
                                <StopStoryboard BeginStoryboardName="Storyboard2"/>
                                <StopStoryboard BeginStoryboardName="Storyboard3"/>
                                <StopStoryboard BeginStoryboardName="Storyboard4"/>
                                <StopStoryboard BeginStoryboardName="Storyboard5"/>
                                <StopStoryboard BeginStoryboardName="Storyboard6"/>
                                <StopStoryboard BeginStoryboardName="Storyboard7"/>
                            </Trigger.ExitActions>
                        </Trigger>
                    </ControlTemplate.Triggers>


                    <!--<StackPanel Orientation="Horizontal">
                        <TextBlock Text="{TemplateBinding MessageText}"/>
                    </StackPanel>-->

                    <Border BorderBrush="{TemplateBinding BorderBrush}" 
                        BorderThickness="{TemplateBinding BorderThickness}" 
                        Background="{TemplateBinding Background}">

                        <Grid>
                            <Canvas Height="60" Width="60">
                                <Canvas.Resources>
                                    <Style TargetType="Ellipse">
                                        <Setter Property="Width" Value="15"/>
                                        <Setter Property="Height" Value="15" />
                                        <Setter Property="Fill" Value="#009B9B9B" />
                                    </Style>
                                </Canvas.Resources>

                                <Ellipse x:Name="ellipse0" Canvas.Left="1.75" Canvas.Top="21"/>
                                <Ellipse x:Name="ellipse1" Canvas.Top="7" Canvas.Left="6.5"/>
                                <Ellipse x:Name="ellipse2" Canvas.Left="20.5" Canvas.Top="0.75"/>
                                <Ellipse x:Name="ellipse3" Canvas.Left="34.75" Canvas.Top="6.75"/>
                                <Ellipse x:Name="ellipse4" Canvas.Left="40.5" Canvas.Top="20.75" />
                                <Ellipse x:Name="ellipse5" Canvas.Left="34.75" Canvas.Top="34.5"/>
                                <Ellipse x:Name="ellipse6" Canvas.Left="20.75" Canvas.Top="39.75"/>
                                <Ellipse x:Name="ellipse7" Canvas.Top="34.25" Canvas.Left="7" />
                                <Ellipse Width="39.5" Height="39.5" Canvas.Left="8.75" Canvas.Top="8" Visibility="Hidden"/>

                                <Label Content="{TemplateBinding MessageText}" 
                                    FontSize="17"
                                    Canvas.Left="60.5" Canvas.Top="11.5"
                                    HorizontalContentAlignment="Center" 
                                    VerticalAlignment="Center"/>

                            </Canvas>
                        </Grid>
                    </Border>

                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</ResourceDictionary>

MyMainWindow.xaml.cs (главное окно для запуска приложения)

using System.ComponentModel;
using System.Windows;

namespace StackHelp
{
    public partial class MyMainWindow : Window, INotifyPropertyChanged
    {
        public MyMainWindow()
        {
            DataContext = this;
            InitializeComponent();
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }


        private string _waitMessageText_1 = "Hi there! I am message 1";
        public string WaitMessageText_1
        {
            get
            {
                return _waitMessageText_1;
            }

            set
            {
                if (_waitMessageText_1 == value) return;
                _waitMessageText_1 = value;

                OnPropertyChanged("WaitMessageText_1");
            }
        }

        private string _waitMessageText_2 = "Hi there! I am message 2";
        public string WaitMessageText_2
        {
            get
            {
                return _waitMessageText_2;
            }

            set
            {
                if (_waitMessageText_2 == value) return;
                _waitMessageText_2 = value;

                OnPropertyChanged("WaitMessageText_2");
            }
        }
    }
}

MyMainWindow.xaml (фактический xaml для главного окна) Здесь у меня есть два экземпляра, один с использованием стиля BASIC, второй с использованием полностью определенного стиля / spinner.

<Window x:Class="StackHelp.MyMainWindow"
    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:myC="clr-namespace:StackHelp.MyClasses"
    Title="My Main Window" Height="250" Width="800">

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*" />
            <ColumnDefinition Width="1*" />
        </Grid.ColumnDefinitions>

        <!-- Instance 1 using the BASIC style version-->
        <myC:UCBusy MessageText="{Binding WaitMessageText_1}" 
            Grid.Column="0" Style="{StaticResource BusyAnimationStyleBasic}" />

        <!-- Instance 2 using the FINAL style version-->
        <myC:UCBusy MessageText="{Binding WaitMessageText_2}" 
            Grid.Column="1" Style="{StaticResource BusyAnimationStyle}"/>

    </Grid>
</Window>

Надеюсь, что это завершит начало ваших собственных стилей и реализаций.

...