I'll start with some Cover refactoring :
I also add an ICoverFactory (mainly for testing purposes) :
- Class becomes internal
- I add the ICover interface, mainly for unit testing with a fake class implementing ICover :
- public interface ICover
- {
- void Animate(int index, bool animate);
- bool Matches(MeshGeometry3D mesh);
- void Destroy();
- }
- 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.
- public interface IThumbnailManager
- {
- ImageSource GetThumbnail(string host, string path);
- }
- internal class Cover : ModelVisual3D, ICover
- {
- ...
- private static IThumbnailManager thumbCache;
- private readonly ModelVisual3D visualModel;
- ...
- private readonly string imageName;
- ...
- private static ImageSource LoadImageSource(ImageInfo info)
- {
- if (thumbCache == null)
- throw new InvalidOperationException("No thumbnail cache.");
- return thumbCache.GetThumbnail(info.Host, info.Path);
- }
- ...
- public Cover(ImageInfo info, int coverPos, int currentPos, ModelVisual3D model)
- {
- pos = coverPos;
- imageName = new FileInfo(info.Path).Name;
- visualModel = model;
- imageSource = LoadImageSource(info);
- modelGroup = new Model3DGroup();
- modelGroup.Children.Add(new GeometryModel3D(Tessellate(), LoadImage(imageSource)));
- modelGroup.Children.Add(new GeometryModel3D(TessellateMirror(), LoadImageMirror(imageSource)));
- rotation = new AxisAngleRotation3D(new Vector3D(0, 1, 0), RotationAngle(currentPos));
- translation = new TranslateTransform3D(TranslationX(currentPos), 0, TranslationZ(currentPos));
- var transformGroup = new Transform3DGroup();
- transformGroup.Children.Add(new RotateTransform3D(rotation));
- transformGroup.Children.Add(translation);
- modelGroup.Transform = transformGroup;
- Content = modelGroup;
- visualModel.Children.Add(this);
- }
- public static IThumbnailManager Cache
- {
- set { thumbCache = value; }
- }
- public void Animate(int index, bool animate)
- {
- if (animate || rotation.HasAnimatedProperties)
- {
- var rotateAnimation = new DoubleAnimation(RotationAngle(index), AnimationDuration);
- var xAnimation = new DoubleAnimation(TranslationX(index), AnimationDuration);
- var zAnimation = new DoubleAnimation(TranslationZ(index), AnimationDuration);
- rotation.BeginAnimation(AxisAngleRotation3D.AngleProperty, rotateAnimation);
- translation.BeginAnimation(TranslateTransform3D.OffsetXProperty, xAnimation);
- translation.BeginAnimation(TranslateTransform3D.OffsetZProperty, zAnimation);
- }
- else
- {
- rotation.Angle = RotationAngle(index);
- translation.OffsetX = TranslationX(index);
- translation.OffsetZ = TranslationZ(index);
- }
- }
- public void Destroy()
- {
- visualModel.Children.Remove(this);
- }
- public override string ToString()
- {
- return string.Format("{0} {1}", pos, imageName);
- }
- }
- public interface ICoverFactory
- {
- ICover NewCover(string host, string path, int coverPos, int currentPos);
- }
- internal class ImageInfo
- {
- public ImageInfo(string host, string path)
- {
- Host = host;
- Path = path;
- }
- public string Host { get; private set; }
- public string Path { get; private set; }
- }
- internal class CoverFactory : ICoverFactory
- {
- private readonly ModelVisual3D visualModel;
- public CoverFactory(ModelVisual3D visualModel)
- {
- this.visualModel = visualModel;
- }
- #region ICoverFactory Members
- public ICover NewCover(string host, string path, int coverPos, int currentPos)
- {
- return new Cover(new ImageInfo(host, path), coverPos, currentPos, visualModel);
- }
- #endregion
- }
The FlowControl class is greatly refactored to implement virtualization.
转载自:http://d3dal3.blogspot.com/2009/04/wpf-cover-flow-tutorial-part-6-bis.html