程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> c#,使用WPF實現iPhone的短信框效果

c#,使用WPF實現iPhone的短信框效果

編輯:C#入門知識

先來看看iPhone的短信界面,就當是麻豆了 ^-^。

 \


 

剛看到這個界面,口水就止不住啊。

擦干口水,趕緊模仿。

 

最初做法:

  基於UserControl,自己做一個用戶控件,內含TextBolck可以實現多行顯示文本,

使用Path和Geometry將帶有小尾巴的圖形畫出來,然後再畫上光照效果,就大功

告成了。

  雖然效果能做出來,但是細細想來,還是有不妥。

  問題就在於,自己作的這個控件,只能顯示文字,為了要顯示圖片,還得寫一堆代碼,

太過死板,為什麼就不能利用WPF的框架或特點,讓這個控件變的靈活一些,只要些

繪圖效果和控制布局的效果就OK了,至於內部包含的是文字還是圖片,就交給WPF去

完成好了。

  基於此,立馬想到為TextBlock控件寫個Template,但稍稍一定神發現,用Template

完成復雜圖形的繪制有些虛無缥缈,結果放棄。

 

思路:

  在老大的點化之下,采用Decorater。乍看之下,有點摸不著北,細細看來,發現,

Border就是從此類繼承而來,說白了就是包含一個子元素的容器,自定義的Decorater

負責繪制圖形背景和管理子元素的顯示,至於顯示的是圖片還是文字就交給子元素去

完成。

  為什麼不用Border而用它,道理就是用它就足夠了,干淨。

 (當然了,容器還有Panel,ContentControl,在這裡用Decorater就夠了)。

 

先看一下最終效果:

 \


 

主要就是用到基類的方法:
    MeasureOverride:通過測量子元素來計算需要的空間的大小。
    ArrangeOverride:排列子元素的顯示位置。
    OnRender:自繪函數,帶小尾巴的圖形繪制就在這裡了,等價於OnPaint。
 
自定義IDecorator類:
public class iDecorator : Decorator {
        public iDecorator() {
            this.HorizontalAlignment = System.Windows.HorizontalAlignment.Right;
        }

        public bool Direction {
            get { return (bool)GetValue(DirectionProperty); }
            set { SetValue(DirectionProperty, value); }
        }

        protected override Size MeasureOverride(Size constraint) {
            Size result = new Size();
            if (Child != null) {
                Child.Measure(constraint);
                result.Width = Child.DesiredSize.Width + padding.Left + padding.Right;
                result.Height = Child.DesiredSize.Height + padding.Top + padding.Bottom;
                if (result.Height < 35) {
                    result.Height = 35;
                    padding.Top = padding.Bottom = (result.Height - Child.DesiredSize.Height) / 2;
                }

            }
            return result;
        }

        protected override Size ArrangeOverride(Size arrangeSize) {
            if (Child != null) {
                Child.Arrange(new Rect(new Point(padding.Left, padding.Top),
                    Child.DesiredSize));
            }
            return arrangeSize;
        }

        protected override void OnRender(DrawingContext dc) {
            if (Child != null) {

                Geometry cg = null;

                Brush brush = null;

                Pen pen = new Pen();

                pen.Brush = new SolidColorBrush(Colors.Black);
                pen.Thickness = 1;

                if (Direction) {
                    //生成小尾巴在右側的圖形和底色
                    cg = CreateGeometryTailAtRight();

                    brush = CreateBrushTailAtRight();
                }
                else {
                    //生成小尾巴在左側的圖形和底色
                    cg = CreateGeometryTailAtLeft();

                    brush = CreateBrushTailAtLeft();
                }

                dc.DrawGeometry(brush, pen, cg);

                //繪制光照效果
                GradientStopCollection gscLight = new GradientStopCollection();
                gscLight.Add(new GradientStop(Color.FromArgb(0xDA, 0xFF, 0xFF, 0xFF), 0));
                gscLight.Add(new GradientStop(Color.FromArgb(0x68, 0xFF, 0xEF, 0xFF), 1));
                Brush lightBrush = new LinearGradientBrush(gscLight, new Point(0, 0), new Point(0, 1));
                dc.DrawRoundedRectangle(lightBrush, null, new Rect(22, 1, this.ActualWidth - 45, 20), 10, 10);

        }
      
        //省略部分代碼。。。

        public static void OnDirectionPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) {
            var self = d as iDecorator;
            self.HorizontalAlignment = (bool)e.NewValue ?
                HorizontalAlignment.Right : HorizontalAlignment.Left;
        }

        private Thickness padding = new Thickness(25, 6, 25, 6);

        public static readonly DependencyProperty DirectionProperty =
            DependencyProperty.Register("Direction", typeof(bool), typeof(iDecorator),
            new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.AffectsRender, OnDirectionPropertyChangedCallback));

        }
 
使用處:
短信框的小尾巴在右側:
                <local:iDecorator HorizontalAlignment="Right" Direction="True">
                    <TextBlock MaxWidth="200" Foreground="Black" TextWrapping="Wrap">前兩天去哪兒了,聽說去北京了???</TextBlock>
                </local:iDecorator>
 
短信框的小尾巴在左側:
就是把Direction(方向)設成False即可。
                <local:iDecorator HorizontalAlignment="Right" Direction="False">
                    <TextBlock MaxWidth="200" Foreground="Black" TextWrapping="Wrap">前兩天去哪兒了,聽說去北京了???</TextBlock>
                </local:iDecorator>
 
大功告成!
雖然還有些細節的效果還差一點,不過,It works。
源代碼:http://files.cnblogs.com/kongxianghai/iMessageDemoSln.rar
開發環境:VS2010,.NetFramWork4.0.

 

摘自  白色的海

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved