C# WPF自定义控件/控件模板

C# WPF自定义控件/控件模板,c#,wpf,data-binding,custom-controls,datatemplate,C#,Wpf,Data Binding,Custom Controls,Datatemplate,我正在使用自定义控件构建一个wpf应用程序,到目前为止一切都正常。 但现在我遇到了两个问题: 我想为我的控件指定一个背景色,但它会覆盖网格内的矩形,因此矩形不可见 我试图为ContentControl编写一个模板,但内容没有按预期呈现,这意味着只有显示名称显示在每个进度条的文本中 自定义控件的模板(如果对隐藏的代码感兴趣,我也将添加该模板): ContentControl的模板: <vm:RamViewModel x:Key="RamInformationSource"/> &

我正在使用自定义控件构建一个wpf应用程序,到目前为止一切都正常。
但现在我遇到了两个问题:

  • 我想为我的控件指定一个背景色,但它会覆盖网格内的矩形,因此矩形不可见
  • 我试图为ContentControl编写一个模板,但内容没有按预期呈现,这意味着只有显示名称显示在每个进度条的文本中 自定义控件的模板(如果对隐藏的代码感兴趣,我也将添加该模板):

    
    
    ContentControl的模板:

    <vm:RamViewModel x:Key="RamInformationSource"/>
    
    <Style TargetType="ContentControl" x:Key="MemoryUsageTemplate">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <Grid DataContext="{Binding Source={StaticResource RamInformationSource}}">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
    
                        <TextBlock HorizontalAlignment="Center" Text="{Binding DisplayName}" VerticalAlignment="Center"
                                   FontSize="15"/>
    
                        <ctrl:MetroProgressBar Grid.Column="1" VerticalAlignment="Stretch" Width="55" Orientation="Vertical" HorizontalAlignment="Center"
                                               ExtenedBorderWidth="0.25" BorderBrush="Gray" Text="Available memory" Progress="{Binding AvailableMemory}"
                                               MaxValue="{Binding TotalMemory}"/>
    
                        <ctrl:MetroProgressBar Grid.Column="2" VerticalAlignment="Stretch" Width="60" Orientation="Vertical" HorizontalAlignment="Center"
                                               ExtenedBorderWidth="0.2" BorderBrush="Black" Text="Total memory" Progress="100"
                                               MaxValue="{Binding TotalMemory}"/>
    
                        <ctrl:MetroProgressBar Grid.Column="3" VerticalAlignment="Stretch" Width="60" Orientation="Vertical" HorizontalAlignment="Center"
                                               ExtenedBorderWidth="0.2" BorderBrush="DodgerBlue" Text="Used memory" Progress="{Binding UsedMemory}"
                                               MaxValue="{Binding TotalMemory}"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    
    
    
    显示内容的xaml:

    ...
    <ContentControl Style="{StaticResource MemoryUsageTemplate}"/>
    
    <ctrl:MetroProgressBar Grid.Row="1" BorderBrush="Black" Text="Test" HorizontalAlignment="Left" Background="Aquamarine"
                           Orientation="Horizontal" BorderThickness="2" Height="50" Width="200" Progress="46"/>
    
    <ctrl:MetroProgressBar Grid.Row="1" BorderBrush="Black" Text="Test" HorizontalAlignment="Right"
                           Orientation="Horizontal" BorderThickness="2" Height="50" Width="200" Progress="46"/>
    ...  
    
    。。。
    ...  
    

    图像顶部显示应用了模板的内容控件。底部显示了上一个xaml中定义的两个进度条(左带背景,右不带背景)。 这些都是为控件定义的自定义DPs:

    /// <summary>
    /// Identifies the ExtenedBorderWidth property.
    /// </summary>
    public static readonly DependencyProperty ExtenedBorderWidthProperty =
        DependencyProperty.Register("ExtenedBorderWidth", typeof(double), typeof(MetroProgressBar),
                                        new PropertyMetadata(0.17, ExtendedBorderWidthValueChanged));
    
    /// <summary>
    /// Identifies the Text property.
    /// </summary>
    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(MetroProgressBar), new PropertyMetadata(""));
    
    /// <summary>
    /// Identifies the Orientation property.
    /// </summary>
    public static readonly DependencyProperty OrientationProperty =
        DependencyProperty.Register("Orientation", typeof(Orientation), typeof(MetroProgressBar), new PropertyMetadata(Orientation.Horizontal, OrientationValueChanged));
    
    /// <summary>
    /// Identifies the IsHorizontal property.
    /// </summary>
    public static readonly DependencyProperty IsHorizontalProperty =
        DependencyProperty.Register("IsHorizontal", typeof(bool), typeof(MetroProgressBar), new PropertyMetadata(true, OrientationChangedByProperty));
    
    /// <summary>
    /// Identifies the IsVertical property.
    /// </summary>
    public static readonly DependencyProperty IsVerticalProperty =
        DependencyProperty.Register("IsVertical", typeof(bool), typeof(MetroProgressBar), new PropertyMetadata(false, OrientationChangedByProperty));
    
    /// <summary>
    /// Identifies the ProgressBrush property.
    /// </summary>
    public static readonly DependencyProperty ProgressBrushProperty =
        DependencyProperty.Register("ProgressBrush", typeof(Brush), typeof(MetroProgressBar), new PropertyMetadata(new SolidColorBrush(Colors.LightGreen)));
    
    /// <summary>
    /// Identifies the LeftBorderTriangle property.
    /// </summary>
    public static readonly DependencyProperty LeftBorderTriangleProperty =
        DependencyProperty.Register("LeftBorderTriangle", typeof(PointCollection), typeof(MetroProgressBar), new PropertyMetadata(new PointCollection()));
    
    /// <summary>
    /// Identifies the RightBorderTriangle property.
    /// </summary>
    public static readonly DependencyProperty RightBorderTriangleProperty =
        DependencyProperty.Register("RightBorderTriangle", typeof(PointCollection), typeof(MetroProgressBar), new PropertyMetadata(new PointCollection()));
    
    /// <summary>
    /// Identifies the MaxValue property.
    /// </summary>
    public static readonly DependencyProperty MaxValueProperty =
        DependencyProperty.Register("MaxValue", typeof(ulong), typeof(MetroProgressBar), new PropertyMetadata(100UL, MaxValueChanged));
    
    /// <summary>
    /// Identifies the Progress property.
    /// </summary>
    public static readonly DependencyProperty ProgressProperty =
        DependencyProperty.Register("Progress", typeof(double), typeof(MetroProgressBar), new PropertyMetadata(0.0d, ProgressValueChanged));
    
    /// <summary>
    /// Identifies the ProgressBarWidth property.
    /// </summary>
    public static readonly DependencyProperty ProgressBarWidthProperty
        = DependencyProperty.Register("ProgressBarWidth", typeof(double), typeof(MetroProgressBar), new PropertyMetadata(0.0d));
    
    /// <summary>
    /// Identifies the ProgressBarHeight property.
    /// </summary>
    public static readonly DependencyProperty ProgressBarHeightProperty
        = DependencyProperty.Register("ProgressBarHeight", typeof(double), typeof(MetroProgressBar), new PropertyMetadata(0.0d));
    
    //
    ///标识ExtendedBorderWidth属性。
    /// 
    公共静态只读从属属性ExtendedBorderWidthProperty=
    DependencyProperty.寄存器(“扩展边界宽度”、typeof(双精度)、typeof(MetroPressBar),
    新属性元数据(0.17,ExtendedBorderWidthValueChanged));
    /// 
    ///标识文本属性。
    /// 
    公共静态只读DependencyProperty TextProperty=
    DependencyProperty.Register(“文本”、typeof(字符串)、typeof(MetroProPressBar)、new PropertyMetadata(“”);
    /// 
    ///标识方向属性。
    /// 
    公共静态只读DependencyProperty方向属性=
    DependencyProperty.Register(“方向”、类型of(方向)、类型of(MetroPressBar)、新属性元数据(方向.水平、方向值更改));
    /// 
    ///标识IsHorizontal属性。
    /// 
    公共静态只读从属属性IsHorizontalProperty=
    DependencyProperty.Register(“IsHorizontal”、typeof(bool)、typeof(MetroProgressBar)、新PropertyMetadata(true、OrientationChangedByProperty));
    /// 
    ///标识IsVertical属性。
    /// 
    公共静态只读从属属性IsVerticalProperty=
    DependencyProperty.Register(“IsVertical”、typeof(bool)、typeof(MetroProgressBar)、新PropertyMetadata(false、OrientionChangedByProperty));
    /// 
    ///标识ProgressBrush属性。
    /// 
    公共静态只读从属属性ProgressBrushProperty=
    DependencyProperty.Register(“ProgressBrush”、typeof(Brush)、typeof(MetroProPressBar)、new PropertyMetadata(new SolidColorBrush(Colors.LightGreen));
    /// 
    ///标识LeftBorderTriangle属性。
    /// 
    公共静态只读从属属性LeftBorderTriangalProperty=
    Register(“LeftBorderTriangle”、typeof(PointCollection)、typeof(MetroProgressBar)、newpropertyMetadata(newpointcollection());
    /// 
    ///标识RightBorderTriangle属性。
    /// 
    公共静态只读从属属性RightBorderTriangleProperty=
    Register(“RightBorderTriangle”、typeof(PointCollection)、typeof(MetroProPressBar)、new PropertyMetadata(new PointCollection());
    /// 
    ///标识MaxValue属性。
    /// 
    公共静态只读从属属性MaxValueProperty=
    DependencyProperty.Register(“MaxValue”、typeof(ulong)、typeof(MetroProgressBar)、新PropertyMetadata(100UL、MaxValueChanged));
    /// 
    ///标识进度属性。
    /// 
    公共静态只读DependencyProperty ProgressProperty=
    DependencyProperty.Register(“Progress”、typeof(double)、typeof(MetroPropressBar)、新PropertyMetadata(0.0d,ProgressValueChanged));
    /// 
    ///标识ProgressBarWidth属性。
    /// 
    公共静态只读DependencyProperty ProgressBarWidthProperty
    =DependencyProperty.Register(“ProgressBarWidth”、typeof(double)、typeof(MetroProgressBar)、new PropertyMetadata(0.0d));
    /// 
    ///标识ProgressBarHeight属性。
    /// 
    公共静态只读从属属性ProgressBarHeightProperty
    =DependencyProperty.Register(“ProgressBarHeight”、typeof(double)、typeof(MetroProgressBar)、new PropertyMetadata(0.0d));
    
    DP值更改了回调和实例方法:

    #region Static
    
    /// <summary>
    /// Changes the orientation based on the calling property.
    /// </summary>
    /// <param name="source">The source of the event.</param>
    /// <param name="e">Event information.</param>
    private static void OrientationChangedByProperty(DependencyObject source, DependencyPropertyChangedEventArgs e)
    {
        //lock (lockOrientationByProperty)
        {
            MetroProgressBar pb = source as MetroProgressBar;
    
            if (e.Property == IsVerticalProperty)
            {
                if ((bool)e.NewValue)
                {
                    pb.IsHorizontal = false;
                    pb.Orientation = Orientation.Vertical;
                }
                else
                {
                    pb.IsHorizontal = true;
                    pb.Orientation = Orientation.Horizontal;
                }
            }
            else
            {
                // IsVerticalProperty is property that changed
                if (!(bool)e.NewValue)
                {
                    pb.IsHorizontal = false;
                    pb.Orientation = Orientation.Vertical;
                }
                else
                {
                    pb.IsHorizontal = true;
                    pb.Orientation = Orientation.Horizontal;
                }
            }
    
            AdjustVisibleProgressRect(pb);
        }
    }
    
    /// <summary>
    /// Sets the progress value to the new maximum value, if the new max value is less than
    /// the current progress value.
    /// </summary>
    /// <param name="source">The source of the event.</param>
    /// <param name="e">Event information.</param>
    private static void MaxValueChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
    {
        //lock (lockMaxValue)
        {
            MetroProgressBar pb = source as MetroProgressBar;
    
            ulong val = Convert.ToUInt64(e.NewValue);
            if (val < Convert.ToUInt64(pb.Progress))
            {
                pb.Progress = val;
    
                // Raise finished event
                pb.OnFinished(EventArgs.Empty);
            }
        }
    }
    
    /// <summary>
    /// Changes the width of the progress indication rectangle of the progress bar.
    /// </summary>
    /// <param name="source">The source of the event.</param>
    /// <param name="e">Event information.</param>
    private static void ProgressValueChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
    {
        //lock (lockProgress)
        {
            MetroProgressBar pb = source as MetroProgressBar;
            AdjustVisibleProgressRect(pb, (double)e.NewValue);
    
            pb.OnProgressChanged(new ProgressChangedEventArgs((double)e.NewValue));
    
            // If new progress value equals or is greater than max value raise the finished event
            if (pb.MaxValue <= Convert.ToUInt64(e.NewValue))
                pb.OnFinished(EventArgs.Empty);
        }
    }
    
    /// <summary>
    /// Changes the width of the progress indication rectangle of the progress bar.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">Event information.</param>
    private static void OrientationValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        //lock (lockOrientation)
        {
            MetroProgressBar pb = sender as MetroProgressBar;
            pb.AdjustToOrientationChange();
    
            if (pb.Orientation == Orientation.Horizontal)
            {
                pb.IsVertical = false;
                pb.IsHorizontal = true;
            }
            else
            {
                pb.IsVertical = true;
                pb.IsHorizontal = false;
            }
    
            pb.OnOrientationChanged(new OrientationChangedEventArgs((Orientation)e.OldValue, (Orientation)e.NewValue));
        }
    }
    
    /// <summary>
    /// Causes the progress bar to reassign the extended border.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">Event information.</param>
    private static void ExtendedBorderWidthValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        //lock (lockExtendedBorder)
        {
            MetroProgressBar pb = sender as MetroProgressBar;
            pb.SetUpBorderParts();
        }
    }
    
    /// <summary>
    /// Adjusts the progress bars visible progress rectangles after progress or visible changes.
    /// </summary>
    /// <param name="pb">The progress bar that changed.</param>
    /// <param name="newValue">The new progress value. Only has to be set if there has been a progress change.</param>
    private static void AdjustVisibleProgressRect(MetroProgressBar pb, double newValue = -1)
    {
        if (pb.Orientation == Orientation.Horizontal)
        {
            pb.ProgressBarWidth = (newValue == -1 ? pb.Progress : newValue) / pb.MaxValue * pb.Width;
        }
        else
        {
            pb.ProgressBarHeight = (newValue == -1 ? pb.Progress : newValue) / pb.MaxValue * pb.Height;
        }
    }
    
    #endregion
    
    #region Non-Static
    
    /// <summary>
    /// Adjusts the border ornaments to the new orientation of the control.
    /// </summary>
    private void AdjustToOrientationChange()
    {
        SetUpBorderParts();
    }
    
    /// <summary>
    /// Sets up the triangles that are placed on the left and right side of the progress bar.
    /// </summary>
    private void SetUpBorderParts()
    {
        PointCollection leftBorder = new PointCollection();
        PointCollection rightBorder = new PointCollection();
    
        double borderWidth = ExtenedBorderWidth;
    
        if (Orientation == Orientation.Horizontal)
        {
            // Left triangle
            leftBorder.Add(new Point(0, 0));
            leftBorder.Add(new Point(0, Height));
            leftBorder.Add(new Point(Width * borderWidth, 0));
    
            // Right triangle
            rightBorder.Add(new Point(Width, 0));
            rightBorder.Add(new Point(Width, Height));
            rightBorder.Add(new Point(Width - (Width * borderWidth), Height));
        }
        else
        {
            // Top border
            leftBorder.Add(new Point(0, 0));
            leftBorder.Add(new Point(Width, 0));
            leftBorder.Add(new Point(0, Height * borderWidth));
    
            // Bottom border
            rightBorder.Add(new Point(0, Height));
            rightBorder.Add(new Point(Width, Height));
            rightBorder.Add(new Point(Width, Height - (Height * borderWidth)));
        }
    
        LeftBorderTriangle = leftBorder;
        RightBorderTriangle = rightBorder;
    }
    
    /// <summary>
    /// Raises the Fnished event.
    /// </summary>
    /// <param name="e">Information on the event.</param>
    protected virtual void OnFinished(EventArgs e)
    {
        EventHandler handler = finished;
    
        if (handler != null)
        {
            handler(this, e);
        }
    }
    
    /// <summary>
    /// Raises the ProgressChanged event.
    /// </summary>
    /// <param name="e">Information on the event.</param>
    protected virtual void OnProgressChanged(ProgressChangedEventArgs e)
    {
        EventHandler<ProgressChangedEventArgs> handler = progressChanged;
    
        if (handler != null)
        {
            handler(this, e);
        }
    }
    
    /// <summary>
    /// Raises the OrientationChanged event.
    /// </summary>
    /// <param name="e">Information on the event.</param>
    protected virtual void OnOrientationChanged(OrientationChangedEventArgs e)
    {
        EventHandler<OrientationChangedEventArgs> handler = orientationChanged;
    
        if (handler != null)
        {
            handler(this, e);
        }
    }
    
    /// <summary>
    /// Raises the RenderSizeChanged event and sets up the border parts.
    /// </summary>
    /// <param name="sizeInfo">Info on the size change.</param>
    protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
    {
        base.OnRenderSizeChanged(sizeInfo);
        SetUpBorderParts();
        AdjustVisibleProgressRect(this);
    }
    
    #endregion
    
    #区域静态
    /// 
    ///根据调用属性更改方向。
    /// 
    ///事件的来源。
    ///事件信息。
    私有静态void方向ChangedByProperty(DependencyObject源、DependencyPropertyChangedEventArgs e)
    {
    //锁定(lockOrientationByProperty)
    {
    MetroPressBar pb=源为MetroPressBar;
    if(e.Property==IsVerticalProperty)
    {
    if((bool)e.NewValue)
    {
    pb.IsHorizontal=假;
    pb.方向=方向垂直;
    }
    其他的
    {
    pb.IsHorizontal=真;
    pb.方向=方向.水平;
    }
    }
    其他的
    {
    //IsVerticalProperty是已更改的属性
    如果(!(bool)e.NewValue)
    {
    pb.IsHorizontal=假;
    pb.方向=方向垂直;
    }
    其他的
    {
    pb.IsHorizontal=真;
    pb.方向=方向.水平;
    }
    }
    可调整可视进度(pb);
    }
    }
    /// 
    ///如果新的最大值为,则将进度值设置为新的最大值
    
    #region Static
    
    /// <summary>
    /// Changes the orientation based on the calling property.
    /// </summary>
    /// <param name="source">The source of the event.</param>
    /// <param name="e">Event information.</param>
    private static void OrientationChangedByProperty(DependencyObject source, DependencyPropertyChangedEventArgs e)
    {
        //lock (lockOrientationByProperty)
        {
            MetroProgressBar pb = source as MetroProgressBar;
    
            if (e.Property == IsVerticalProperty)
            {
                if ((bool)e.NewValue)
                {
                    pb.IsHorizontal = false;
                    pb.Orientation = Orientation.Vertical;
                }
                else
                {
                    pb.IsHorizontal = true;
                    pb.Orientation = Orientation.Horizontal;
                }
            }
            else
            {
                // IsVerticalProperty is property that changed
                if (!(bool)e.NewValue)
                {
                    pb.IsHorizontal = false;
                    pb.Orientation = Orientation.Vertical;
                }
                else
                {
                    pb.IsHorizontal = true;
                    pb.Orientation = Orientation.Horizontal;
                }
            }
    
            AdjustVisibleProgressRect(pb);
        }
    }
    
    /// <summary>
    /// Sets the progress value to the new maximum value, if the new max value is less than
    /// the current progress value.
    /// </summary>
    /// <param name="source">The source of the event.</param>
    /// <param name="e">Event information.</param>
    private static void MaxValueChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
    {
        //lock (lockMaxValue)
        {
            MetroProgressBar pb = source as MetroProgressBar;
    
            ulong val = Convert.ToUInt64(e.NewValue);
            if (val < Convert.ToUInt64(pb.Progress))
            {
                pb.Progress = val;
    
                // Raise finished event
                pb.OnFinished(EventArgs.Empty);
            }
        }
    }
    
    /// <summary>
    /// Changes the width of the progress indication rectangle of the progress bar.
    /// </summary>
    /// <param name="source">The source of the event.</param>
    /// <param name="e">Event information.</param>
    private static void ProgressValueChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
    {
        //lock (lockProgress)
        {
            MetroProgressBar pb = source as MetroProgressBar;
            AdjustVisibleProgressRect(pb, (double)e.NewValue);
    
            pb.OnProgressChanged(new ProgressChangedEventArgs((double)e.NewValue));
    
            // If new progress value equals or is greater than max value raise the finished event
            if (pb.MaxValue <= Convert.ToUInt64(e.NewValue))
                pb.OnFinished(EventArgs.Empty);
        }
    }
    
    /// <summary>
    /// Changes the width of the progress indication rectangle of the progress bar.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">Event information.</param>
    private static void OrientationValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        //lock (lockOrientation)
        {
            MetroProgressBar pb = sender as MetroProgressBar;
            pb.AdjustToOrientationChange();
    
            if (pb.Orientation == Orientation.Horizontal)
            {
                pb.IsVertical = false;
                pb.IsHorizontal = true;
            }
            else
            {
                pb.IsVertical = true;
                pb.IsHorizontal = false;
            }
    
            pb.OnOrientationChanged(new OrientationChangedEventArgs((Orientation)e.OldValue, (Orientation)e.NewValue));
        }
    }
    
    /// <summary>
    /// Causes the progress bar to reassign the extended border.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">Event information.</param>
    private static void ExtendedBorderWidthValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        //lock (lockExtendedBorder)
        {
            MetroProgressBar pb = sender as MetroProgressBar;
            pb.SetUpBorderParts();
        }
    }
    
    /// <summary>
    /// Adjusts the progress bars visible progress rectangles after progress or visible changes.
    /// </summary>
    /// <param name="pb">The progress bar that changed.</param>
    /// <param name="newValue">The new progress value. Only has to be set if there has been a progress change.</param>
    private static void AdjustVisibleProgressRect(MetroProgressBar pb, double newValue = -1)
    {
        if (pb.Orientation == Orientation.Horizontal)
        {
            pb.ProgressBarWidth = (newValue == -1 ? pb.Progress : newValue) / pb.MaxValue * pb.Width;
        }
        else
        {
            pb.ProgressBarHeight = (newValue == -1 ? pb.Progress : newValue) / pb.MaxValue * pb.Height;
        }
    }
    
    #endregion
    
    #region Non-Static
    
    /// <summary>
    /// Adjusts the border ornaments to the new orientation of the control.
    /// </summary>
    private void AdjustToOrientationChange()
    {
        SetUpBorderParts();
    }
    
    /// <summary>
    /// Sets up the triangles that are placed on the left and right side of the progress bar.
    /// </summary>
    private void SetUpBorderParts()
    {
        PointCollection leftBorder = new PointCollection();
        PointCollection rightBorder = new PointCollection();
    
        double borderWidth = ExtenedBorderWidth;
    
        if (Orientation == Orientation.Horizontal)
        {
            // Left triangle
            leftBorder.Add(new Point(0, 0));
            leftBorder.Add(new Point(0, Height));
            leftBorder.Add(new Point(Width * borderWidth, 0));
    
            // Right triangle
            rightBorder.Add(new Point(Width, 0));
            rightBorder.Add(new Point(Width, Height));
            rightBorder.Add(new Point(Width - (Width * borderWidth), Height));
        }
        else
        {
            // Top border
            leftBorder.Add(new Point(0, 0));
            leftBorder.Add(new Point(Width, 0));
            leftBorder.Add(new Point(0, Height * borderWidth));
    
            // Bottom border
            rightBorder.Add(new Point(0, Height));
            rightBorder.Add(new Point(Width, Height));
            rightBorder.Add(new Point(Width, Height - (Height * borderWidth)));
        }
    
        LeftBorderTriangle = leftBorder;
        RightBorderTriangle = rightBorder;
    }
    
    /// <summary>
    /// Raises the Fnished event.
    /// </summary>
    /// <param name="e">Information on the event.</param>
    protected virtual void OnFinished(EventArgs e)
    {
        EventHandler handler = finished;
    
        if (handler != null)
        {
            handler(this, e);
        }
    }
    
    /// <summary>
    /// Raises the ProgressChanged event.
    /// </summary>
    /// <param name="e">Information on the event.</param>
    protected virtual void OnProgressChanged(ProgressChangedEventArgs e)
    {
        EventHandler<ProgressChangedEventArgs> handler = progressChanged;
    
        if (handler != null)
        {
            handler(this, e);
        }
    }
    
    /// <summary>
    /// Raises the OrientationChanged event.
    /// </summary>
    /// <param name="e">Information on the event.</param>
    protected virtual void OnOrientationChanged(OrientationChangedEventArgs e)
    {
        EventHandler<OrientationChangedEventArgs> handler = orientationChanged;
    
        if (handler != null)
        {
            handler(this, e);
        }
    }
    
    /// <summary>
    /// Raises the RenderSizeChanged event and sets up the border parts.
    /// </summary>
    /// <param name="sizeInfo">Info on the size change.</param>
    protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
    {
        base.OnRenderSizeChanged(sizeInfo);
        SetUpBorderParts();
        AdjustVisibleProgressRect(this);
    }
    
    #endregion