c#,使用WPF的Adorner实现iPhone上新邮件或消息提示效果----实现(一)

一、背景介绍

首先,让我们看一下iPhone上的新邮件提示效果。

c#,使用WPF的Adorner实现iPhone上新邮件或消息提示效果----实现(一)_第1张图片

在邮件图标的右上角会出现未读的新邮件数量,苹果的这种设计即简洁又精致,而且相当的实用。

那么经典的效果当然要用我们的实际行动来膜拜!^_^

 

二、最终效果预览

    在该篇文章的最后分享了代码,^_^。

    c#,使用WPF的Adorner实现iPhone上新邮件或消息提示效果----实现(一)_第2张图片

 

三、实现分解

    结构采用自定义按钮+自定义装饰件(Adorner)。

    装饰件顾名思义就是用来作装饰用的,好处就是:我们以前都是自己写个控件然后在控件上绘制所有的效果,

而现在有了它,我们可以将一些效果独立出来做成一种装饰件,重用在其他想使用该效果的控件上,增强了

效果的解耦和重用。

c#,使用WPF的Adorner实现iPhone上新邮件或消息提示效果----实现(一)_第3张图片

 

1、自定义按钮(PromptableButton)

   接下来我们编写一个继承自Button类的PromptableButton。

internal class PromptableButton : Button {
    //省略...
}

 

   该按钮需要一个提示数量(PromptCount)属性用于最终的右上角提示显示用,做成依赖属性是为了绑定给用作显示的XAML代码。

   CoercePromptCountCallback用于限制PromptCount不能小于0。

        public int PromptCount {
            get { return (int)GetValue(PromptCountProperty); }
            set { SetValue(PromptCountProperty, value); }
        }

        public static readonly DependencyProperty PromptCountProperty =
            DependencyProperty.Register("PromptCount", typeof(int), typeof(PromptableButton), 
            new FrameworkPropertyMetadata(0, new PropertyChangedCallback(PromptCountChangedCallBack),
new CoerceValueCallback(CoercePromptCountCallback))); private static object CoercePromptCountCallback(DependencyObject d, object value) { int promptCount = (int)value; promptCount = Math.Max(0, promptCount); return promptCount; }

 

    该按钮还需要一个封面图片,同样做成依赖属性绑定给界面。

        public ImageSource CoverImageSource {
            get { return (ImageSource)GetValue(CoverImageSourceProperty); }
            set { SetValue(CoverImageSourceProperty, value); }
        }

        public static readonly DependencyProperty CoverImageSourceProperty =
            DependencyProperty.Register("CoverImageSource", typeof(ImageSource), typeof(PromptableButton), new UIPropertyMetadata(null));

 

    因为是自定义按钮,我们需要为该按钮提供一个皮肤,皮肤写在Themes/Generic.xaml资源文件中。

    为了应用该皮肤,我们如此做:

       static PromptableButton() {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(PromptableButton), new FrameworkPropertyMetadata(typeof(PromptableButton)));
        }

    

    接下来,看看皮肤的实现。

    其中的PART_CoverImage的Source绑定PromptableButton的CoverImageSource属性,用来显示封面图片。

    下面的触发器的作用是当按下按钮后对按钮作模糊效果。

    

    自定义按钮(PromptableButton)完成。

2、自定义装饰件(PromptAdorner)

    我们一般都会在Adorner的OnRender方法里实现装饰件的绘制,如果绘制的话需要监听PromptableButton的PromptCount

属性的变化,这样作就显得比较麻烦,依赖属性本身就是用作绑定的最好的对象,为什们我们不能使用XAML来作绘制,并且绑定

PromptCount!

    为此,专门做一个负责绘制PromptCount的自定义控件(PromptChrome),为这个控件做一个皮肤,在此皮肤内绑定

PromptCount,并且将这个控件作为装饰件(PromptAdorner)的子控件,说白了就是PromptAdorner负责装饰,装饰些什么东

西则交给PromptChrome来完成。

    首先,让我们看看PromptAdorner的代码。

    其目的就是管理子控件PromptChrome,并通过ArrangeOverride方法进行布局。

    注意其中的_chrome.DataContext = adornedElement;这句话使PromptableButton成为PromptChrome的上下文,

使PromptCount被PromptChrome界面上的元素绑定。

 

    internal class PromptAdorner : Adorner {

        protected override int VisualChildrenCount {
            get { return 1; }
        }

        public PromptAdorner(UIElement adornedElement)
            : base(adornedElement) {

            _chrome = new PromptChrome();
            _chrome.DataContext = adornedElement;
            this.AddVisualChild(_chrome);
        }

        protected override Visual GetVisualChild(int index) {
            return _chrome;
        }

        protected override Size ArrangeOverride(Size arrangeBounds) {
            _chrome.Arrange(new Rect(arrangeBounds));
            return arrangeBounds;
        }
        
        PromptChrome _chrome;
    }

 

    接下来,我们看一下PromptChrome的代码。

    在静态构造中应用皮肤。

    在ArrangeOverride布局方法中,将自己放置到右上角。

    internal class PromptChrome : Control {
        static PromptChrome() {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(PromptChrome), new FrameworkPropertyMetadata(typeof(PromptChrome)));
        }     

        protected override Size ArrangeOverride(Size arrangeBounds) {

            this.Width = 34;
            this.Height = 34;

            this.HorizontalAlignment = System.Windows.HorizontalAlignment.Right;
            this.VerticalAlignment = System.Windows.VerticalAlignment.Top;

            TranslateTransform tt = new TranslateTransform();
            tt.X = 10;
            tt.Y = -10;
            this.RenderTransform = tt;

            return base.ArrangeOverride(arrangeBounds);
        }
    }

 

     接下来是PromptChrome的皮肤。

     提示效果的绘制,绑定PromptCount都在内,可参考注释。

    

 

四、代码

http://download.csdn.net/download/kongxh_1981/9161573

 

你可能感兴趣的:(c#,使用WPF的Adorner实现iPhone上新邮件或消息提示效果----实现(一))