WPF Cover Flow Tutorial : Part 6 (bis)

来源:互联网 发布:免费开源的实时数据库 编辑:程序博客网 时间:2024/05/01 17:45
I'll start with some Cover refactoring :
  • Class becomes internal
  • I add the ICover interface, mainly for unit testing with a fake class implementing ICover :
    view plainprint?
    1. public interface ICover  
    2. {  
    3.    void Animate(int index, bool animate);  
    4.    bool Matches(MeshGeometry3D mesh);  
    5.    void Destroy();  
    6. }  
  • You may notice the new Destroy method. This is useful to be able to create or destroy objects at will. Relatively, covers now know about the containing ModelVisual3D.
  • I also add a static IThumbnailManager to put elsewhere all the code dealing with thumbnails (like managing an IsolatedStorageFile for example)
  • Animation is slightly modified : in some cases, no rotation is needed to allow faster browsing.
Here are the changes since Part 5 :
view plainprint?
  1. public interface IThumbnailManager  
  2. {  
  3.     ImageSource GetThumbnail(string host, string path);  
  4. }  
  5. internal class Cover : ModelVisual3D, ICover  
  6. {  
  7.     ...  
  8.     private static IThumbnailManager thumbCache;  
  9.     private readonly ModelVisual3D visualModel;  
  10.     ...  
  11.     private readonly string imageName;  
  12.     ...  
  13.     private static ImageSource LoadImageSource(ImageInfo info)  
  14.     {  
  15.         if (thumbCache == null)  
  16.             throw new InvalidOperationException("No thumbnail cache.");  
  17.         return thumbCache.GetThumbnail(info.Host, info.Path);  
  18.     }  
  19.     ...  
  20.     public Cover(ImageInfo info, int coverPos, int currentPos, ModelVisual3D model)  
  21.     {  
  22.         pos = coverPos;  
  23.         imageName = new FileInfo(info.Path).Name;  
  24.         visualModel = model;  
  25.   
  26.         imageSource = LoadImageSource(info);  
  27.         modelGroup = new Model3DGroup();  
  28.         modelGroup.Children.Add(new GeometryModel3D(Tessellate(), LoadImage(imageSource)));  
  29.         modelGroup.Children.Add(new GeometryModel3D(TessellateMirror(), LoadImageMirror(imageSource)));  
  30.   
  31.         rotation = new AxisAngleRotation3D(new Vector3D(0, 1, 0), RotationAngle(currentPos));  
  32.         translation = new TranslateTransform3D(TranslationX(currentPos), 0, TranslationZ(currentPos));  
  33.         var transformGroup = new Transform3DGroup();  
  34.         transformGroup.Children.Add(new RotateTransform3D(rotation));  
  35.         transformGroup.Children.Add(translation);  
  36.         modelGroup.Transform = transformGroup;  
  37.   
  38.         Content = modelGroup;  
  39.   
  40.         visualModel.Children.Add(this);  
  41.     }  
  42.     public static IThumbnailManager Cache  
  43.     {  
  44.         set { thumbCache = value; }  
  45.     }  
  46.     public void Animate(int index, bool animate)  
  47.     {  
  48.         if (animate || rotation.HasAnimatedProperties)  
  49.         {  
  50.             var rotateAnimation = new DoubleAnimation(RotationAngle(index), AnimationDuration);  
  51.             var xAnimation = new DoubleAnimation(TranslationX(index), AnimationDuration);  
  52.             var zAnimation = new DoubleAnimation(TranslationZ(index), AnimationDuration);  
  53.             rotation.BeginAnimation(AxisAngleRotation3D.AngleProperty, rotateAnimation);  
  54.             translation.BeginAnimation(TranslateTransform3D.OffsetXProperty, xAnimation);  
  55.             translation.BeginAnimation(TranslateTransform3D.OffsetZProperty, zAnimation);  
  56.         }  
  57.         else  
  58.         {  
  59.             rotation.Angle = RotationAngle(index);  
  60.             translation.OffsetX = TranslationX(index);  
  61.             translation.OffsetZ = TranslationZ(index);  
  62.         }  
  63.     }  
  64.     public void Destroy()  
  65.     {  
  66.         visualModel.Children.Remove(this);  
  67.     }  
  68.     public override string ToString()  
  69.     {  
  70.         return string.Format("{0} {1}", pos, imageName);  
  71.     }  
  72. }  
I also add an ICoverFactory (mainly for testing purposes) :
view plainprint?
  1. public interface ICoverFactory  
  2. {  
  3.     ICover NewCover(string host, string path, int coverPos, int currentPos);  
  4. }  
  5. internal class ImageInfo  
  6. {  
  7.     public ImageInfo(string host, string path)  
  8.     {  
  9.         Host = host;  
  10.         Path = path;  
  11.     }  
  12.     public string Host { getprivate set; }  
  13.     public string Path { getprivate set; }  
  14. }  
  15. internal class CoverFactory : ICoverFactory  
  16. {  
  17.     private readonly ModelVisual3D visualModel;  
  18.     public CoverFactory(ModelVisual3D visualModel)  
  19.     {  
  20.         this.visualModel = visualModel;  
  21.     }  
  22.     #region ICoverFactory Members  
  23.     public ICover NewCover(string host, string path, int coverPos, int currentPos)  
  24.     {  
  25.         return new Cover(new ImageInfo(host, path), coverPos, currentPos, visualModel);  
  26.     }  
  27.     #endregion  
  28. }  

The FlowControl class is greatly refactored to implement virtualization.

转载自:http://d3dal3.blogspot.com/2009/04/wpf-cover-flow-tutorial-part-6-bis.html