| Gustavo's profilementasBlogListsSkyDrive | Help |
|
|
November 24 ItemsFeedHere's my proposal to break the limitations of current data/web feeds formats
Concepts:
<ItemsFeed Version="1.0"> <Collection Name=""> <Collection.Schema> <!-- Types: Text, Number, Date, Bytes, Links Formats (samples): Text (mask), Number (D2), Date (dddd, dd MMMM yyyy HH:mm), Bytes (xml/jpg/pdf), Links (File/HTTP/CollectionName[ItemID]) IsFilter: True/False --> <Property Name="" Type="" Format="" IsFilter="" /> </Collection.Schema> <Collection.Template> <!-- Samples: xaml, html --> </Collection.Template> <!-- ID: ULong/Guid --> <Item ID="" Title="" Description="" Date="" State="" Author=""> <Property Name=""></Property> <!-- <Property Name=""> <Link></Link> <Link></Link> <Link></Link> </Property> --> </Item> </Collection> </ItemsFeed> November 15 NavigableDynamicItem (Part II)A navigable version of DynamicItem. Now you can define forward/backward behaviors.
NavigableDynamicItem.cs public class NavigableDynamicItem : Control { private object temp_data = null;
public NavigableDynamicItem() { this.DefaultStyleKey = typeof(NavigableDynamicItem); }
public override void OnApplyTemplate() { base.OnApplyTemplate();
FrameworkElement root = (FrameworkElement)GetTemplateChild("LayoutRoot"); if (root == null) throw new Exception("'LayourRoot' element not found.");
((VisualStateGroup)VisualStateManager.GetVisualStateGroups(root)[0]).CurrentStateChanged += new EventHandler<VisualStateChangedEventArgs>(DynamicItem_CurrentStateChanged);
VisualStateManager.GoToState(this, "ForwardEnter", false); }
private void DynamicItem_CurrentStateChanged(object sender, VisualStateChangedEventArgs e) { if (e.NewState.Name == "ForwardLeave") { DispatcherTimer delay = new DispatcherTimer() { Interval = EnterDelay }; delay.Tick += delegate { DataContext = temp_data; temp_data = null;
VisualStateManager.GoToState(this, "ForwardEnter", false); delay.Stop(); delay = null; }; delay.Start(); } else if (e.NewState.Name == "ForwardEnter" && DataContext != null) VisualStateManager.GoToState(this, "Normal", true);
if (e.NewState.Name == "BackwardLeave") { DispatcherTimer delay = new DispatcherTimer() { Interval = EnterDelay }; delay.Tick += delegate { DataContext = temp_data; temp_data = null;
VisualStateManager.GoToState(this, "BackwardEnter", false); delay.Stop(); delay = null; }; delay.Start(); } else if (e.NewState.Name == "BackwardEnter" && DataContext != null) VisualStateManager.GoToState(this, "Normal", true); }
public void ChangeDataContextForward(object data) { temp_data = data;
DispatcherTimer delay = new DispatcherTimer() { Interval = LeaveDelay }; delay.Tick += delegate { VisualStateManager.GoToState(this, "ForwardLeave", DataContext != null); delay.Stop(); delay = null; }; delay.Start(); } public void ChangeDataContextBackward(object data) { temp_data = data;
DispatcherTimer delay = new DispatcherTimer() { Interval = LeaveDelay }; delay.Tick += delegate { VisualStateManager.GoToState(this, "BackwardLeave", DataContext != null); delay.Stop(); delay = null; }; delay.Start(); }
[Category("NavigableDynamicItem")] public TimeSpan EnterDelay { get; set; } [Category("NavigableDynamicItem")] public TimeSpan LeaveDelay { get; set; } } NavigableDynamicItem (Part I)A navigable version of DynamicItem. Now you can define forward/backward behaviors.
Generic.xaml <Style TargetType="local:NavigableDynamicItem"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="local:NavigableDynamicItem"> <Border x:Name="LayoutRoot" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}"> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="TransitionStates"> <VisualStateGroup.Transitions> <VisualTransition GeneratedDuration="00:00:00.5000000"/> <VisualTransition GeneratedDuration="00:00:00" To="ForwardEnter"/> <VisualTransition GeneratedDuration="00:00:00" To="BackwardEnter"/> </VisualStateGroup.Transitions> <VisualState x:Name="Normal"/> <VisualState x:Name="ForwardEnter"/> <VisualState x:Name="ForwardLeave"/> <VisualState x:Name="BackwardEnter"/> <VisualState x:Name="BackwardLeave"/> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <TextBlock Text="{Binding }" HorizontalAlignment="Center" VerticalAlignment="Center" /> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style>TickerYou can use this panel as ItemsPanelTemplate on ItemsControl, ListBox, ...
Note: For a better control over delta FPS use a Storyboard instead DispatcherTimer.
public class Ticker : Canvas { public static readonly DependencyProperty DelayProperty; public static readonly DependencyProperty DeltaProperty;
private double pos = 0;
static Ticker() { DelayProperty = DependencyProperty.Register("Delay", typeof(TimeSpan), typeof(Ticker), new PropertyMetadata(TimeSpan.Zero)); DeltaProperty = DependencyProperty.Register("Delta", typeof(double), typeof(Ticker), new PropertyMetadata(2.0)); }
public Ticker() : base() { ClipToBounds = true;
Loaded += new RoutedEventHandler(Ticker_Loaded); }
public void Ticker_Loaded(object sender, RoutedEventArgs e) { foreach (FrameworkElement fe in Children) { pos = ActualWidth; Canvas.SetLeft(fe, ActualWidth); }
DispatcherTimer delay_timer = new DispatcherTimer() { Interval = Delay }; delay_timer.Tick += delegate { DispatcherTimer delta_timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(10) }; delta_timer.Tick += delegate { foreach (FrameworkElement fe in Children) { pos -= Delta; if (pos + fe.ActualWidth < 0) pos = ActualWidth;
Canvas.SetLeft(fe, pos); } }; delta_timer.Start();
delay_timer.Stop(); }; delay_timer.Start(); }
[Category("Ticker")] public TimeSpan Delay { get { return (TimeSpan)GetValue(DelayProperty); } set { SetValue(DelayProperty, value); } } [Category("Ticker")] public double Delta { get { return (double)GetValue(DeltaProperty); } set { SetValue(DeltaProperty, value); } } } WPF/SL binding converters (Part III)Plain text and image extraction from HTML...
public class TextConverter : IValueConverter { #region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return Regex.Replace((string)value, @"<[^>]*>", string.Empty).Trim(); }
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); }
#endregion }
public class ImageConverter : IValueConverter { #region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { MatchCollection matches = Regex.Matches((string)value, "src=(?:\"|\')?(?<imgSrc>[^>]*[^/].(?:jpg|png))(?:\"|\')?");
if (matches.Count > 0) { if (parameter != null) return matches[int.Parse((string)parameter)].Groups[1].Value; else return matches[0].Groups[1].Value; }
return ""; }
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); }
#endregion } WPF/SL binding converters (Part II)XmlDataProvider (Text, Number and DateTime) sorting...
public class TextSortConverter : IValueConverter { #region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value != null) { string[] args = ((string)parameter).Split(' ');
ICollection col = (ICollection)value;
List<string> aux = null;
if (args.Length == 2 && args[1] == "desc") { aux = (from item in col.Cast<XmlElement>() orderby item[args[0]].InnerText descending select item.InnerXml).ToList(); } else { aux = (from item in col.Cast<XmlElement>() orderby item[args[0]].InnerText select item.InnerXml).ToList(); }
int i = 0; foreach (XmlElement e in col) { e.InnerXml = aux[i]; i++; } }
return value; }
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); }
#endregion }
public class NumericSortConverter : IValueConverter { #region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value != null) { string[] args = ((string)parameter).Split(' ');
ICollection col = (ICollection)value;
List<string> aux = null;
if (args.Length == 2 && args[1] == "desc") { aux = (from item in col.Cast<XmlElement>() orderby double.Parse(item[args[0]].InnerText.Replace(".", ",")) descending select item.InnerXml).ToList(); } else { aux = (from item in col.Cast<XmlElement>() orderby double.Parse(item[args[0]].InnerText.Replace(".", ",")) select item.InnerXml).ToList(); }
int i = 0; foreach (XmlElement e in col) { e.InnerXml = aux[i]; i++; } }
return value; }
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); }
#endregion }
public class DateTimeSortConverter : IValueConverter { #region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value != null) { string[] args = ((string)parameter).Split(' ');
ICollection col = (ICollection)value;
List<string> aux = null;
if (args.Length == 2 && args[1] == "desc") { aux = (from item in col.Cast<XmlElement>() orderby DateTime.Parse(item[args[0]].InnerText) descending select item.InnerXml).ToList(); } else { aux = (from item in col.Cast<XmlElement>() orderby DateTime.Parse(item[args[0]].InnerText) select item.InnerXml).ToList(); }
int i = 0; foreach (XmlElement e in col) { e.InnerXml = aux[i]; i++; } }
return value; }
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); }
#endregion } WPF/SL binding converters (Part I)Number round and DateTime format...
public class NumericConverter : IValueConverter { #region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (!string.IsNullOrEmpty((string)value) && parameter != null) { string num = Math.Round(double.Parse(((string)value).Replace(".", ",")), int.Parse((string)parameter)).ToString();
string[] dc = num.Split(','); int dc_num = 0; if (dc.Length == 2) dc_num = dc[1].Length;
for (int i = dc_num; i < int.Parse((string)parameter); i++) num += "0";
return num; } else return value; }
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); }
#endregion }
public class DateTimeConverter : IValueConverter { #region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { string dt = value.ToString();
ulong aux = 0; if (ulong.TryParse(dt, out aux)) { if (dt.Length == 8) return new DateTime(int.Parse(dt.Substring(0, 4)), int.Parse(dt.Substring(4, 2)), int.Parse(dt.Substring(6, 2))).ToString((string)parameter); else if (dt.Length == 10) return new DateTime(int.Parse(dt.Substring(0, 4)), int.Parse(dt.Substring(4, 2)), int.Parse(dt.Substring(6, 2)), int.Parse(dt.Substring(8, 2)), 0, 0).ToString((string)parameter); else if (dt.Length == 12) return new DateTime(int.Parse(dt.Substring(0, 4)), int.Parse(dt.Substring(4, 2)), int.Parse(dt.Substring(6, 2)), int.Parse(dt.Substring(8, 2)), int.Parse(dt.Substring(10, 2)), 0).ToString((string)parameter); else if (dt.Length == 14) return new DateTime(int.Parse(dt.Substring(0, 4)), int.Parse(dt.Substring(4, 2)), int.Parse(dt.Substring(6, 2)), int.Parse(dt.Substring(8, 2)), int.Parse(dt.Substring(10, 2)), int.Parse(dt.Substring(12, 2))).ToString((string)parameter); else return new DateTime(long.Parse(dt)).ToString((string)parameter); } else return DateTime.Parse(dt).ToString((string)parameter); }
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); }
#endregion } November 14 DynamicItemThe ideia is something like "TransitionControl" concept (included in SL Toolkit), but using DataContext (Binding/Templating) and VisualStates. DynamicItem is a Control and must to be templated and the entering/leaving behaviors defined using the three states (Normal, Enter, Leave). Call ChangeDataContext method to change data and invoke transition states. If you need a composition between transition items, use two or more DynamicItem's (you can set an Enter/Leave delay time)... or simple prepare the Template and the DataContext to receive two items (new and old).
Generic.xaml <Style TargetType="local:DynamicItem"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="local:DynamicItem"> <Border x:Name="LayoutRoot" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}"> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="TransitionStates"> <VisualStateGroup.Transitions> <VisualTransition GeneratedDuration="00:00:00.5000000"/> <VisualTransition GeneratedDuration="00:00:00" To="Enter"/> </VisualStateGroup.Transitions> <VisualState x:Name="Normal"/> <VisualState x:Name="Enter"/> <VisualState x:Name="Leave"/> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <TextBlock Text="{Binding }" HorizontalAlignment="Center" VerticalAlignment="Center" /> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style>
DynamicItem.cs
public class DynamicItem : Control { private object temp_data = null;
public DynamicItem() { this.DefaultStyleKey = typeof(DynamicItem); }
public override void OnApplyTemplate() { base.OnApplyTemplate();
FrameworkElement root = (FrameworkElement)GetTemplateChild("LayoutRoot"); if (root == null) throw new Exception("'LayourRoot' element not found.");
((VisualStateGroup)VisualStateManager.GetVisualStateGroups(root)[0]).CurrentStateChanged += new EventHandler<VisualStateChangedEventArgs>(DynamicItem_CurrentStateChanged);
VisualStateManager.GoToState(this, "Enter", false); }
private void DynamicItem_CurrentStateChanged(object sender, VisualStateChangedEventArgs e) { if (e.NewState.Name == "Leave") { DispatcherTimer delay = new DispatcherTimer() { Interval = EnterDelay }; delay.Tick += delegate { DataContext = temp_data; temp_data = null;
VisualStateManager.GoToState(this, "Enter", false); delay.Stop(); delay = null; }; delay.Start(); } else if (e.NewState.Name == "Enter" && DataContext != null) VisualStateManager.GoToState(this, "Normal", true); }
public void ChangeDataContext(object data) { temp_data = data;
DispatcherTimer delay = new DispatcherTimer() { Interval = LeaveDelay }; delay.Tick += delegate { VisualStateManager.GoToState(this, "Leave", DataContext != null); delay.Stop(); delay = null; }; delay.Start(); }
[Category("DynamicItem")] public TimeSpan EnterDelay { get; set; } [Category("DynamicItem")] public TimeSpan LeaveDelay { get; set; } } November 03 ZoomboxBasic implementation of "Blendables Essentials Mix" concept for Silverlight.
Generic.xaml
<Style TargetType="local:Zoombox"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="local:Zoombox"> <Canvas x:Name="Container"> <ContentPresenter> <ContentPresenter.RenderTransform> <TransformGroup> <ScaleTransform x:Name="Zoom" /> <TranslateTransform x:Name="Pan" /> </TransformGroup> </ContentPresenter.RenderTransform> </ContentPresenter> </Canvas> </ControlTemplate> </Setter.Value> </Setter> </Style> Zoombox.cs
public class Zoombox : ContentControl { private Canvas container = null; private ScaleTransform zoom = null; private TranslateTransform pan = null;
public Zoombox() { this.DefaultStyleKey = typeof(Zoombox);
ZoomMargin = 10; }
public override void OnApplyTemplate() { base.OnApplyTemplate();
container = (Canvas)GetTemplateChild("Container"); zoom = (ScaleTransform)GetTemplateChild("Zoom"); pan = (TranslateTransform)GetTemplateChild("Pan"); }
public void ZoomTo(Rect rect) { rect.X = rect.X - ZoomMargin / 2; rect.Y = rect.Y - ZoomMargin / 2; rect.Width = rect.Width + ZoomMargin; rect.Height = rect.Height + ZoomMargin;
double factor = Math.Min(container.ActualWidth / rect.Width, container.ActualHeight / rect.Height); zoom.ScaleY = zoom.ScaleX = factor;
pan.X = (container.ActualWidth - rect.Width * factor) / 2 - rect.X * factor; pan.Y = (container.ActualHeight - rect.Height * factor) / 2 - rect.Y * factor; } public void ZoomTo(Rect rect, TimeSpan duration) { ZoomTo(rect, duration, null); } public void ZoomTo(Rect rect, TimeSpan duration, IEasingFunction func) { rect.X = rect.X - ZoomMargin / 2; rect.Y = rect.Y - ZoomMargin / 2; rect.Width = rect.Width + ZoomMargin; rect.Height = rect.Height + ZoomMargin;
double factor = Math.Min(container.ActualWidth / rect.Width, container.ActualHeight / rect.Height);
double panx = (container.ActualWidth - rect.Width * factor) / 2 - rect.X * factor; double pany = (container.ActualHeight - rect.Height * factor) / 2 - rect.Y * factor;
Storyboard sb = new Storyboard();
DoubleAnimation zoomx_anim = new DoubleAnimation() { To = factor, Duration = duration, EasingFunction = func }; Storyboard.SetTarget(zoomx_anim, zoom); Storyboard.SetTargetProperty(zoomx_anim, new PropertyPath("ScaleX"));
DoubleAnimation zoomy_anim = new DoubleAnimation() { To = factor, Duration = duration, EasingFunction = func }; Storyboard.SetTarget(zoomy_anim, zoom); Storyboard.SetTargetProperty(zoomy_anim, new PropertyPath("ScaleY"));
DoubleAnimation panx_anim = new DoubleAnimation() { To = panx, Duration = duration, EasingFunction = func }; Storyboard.SetTarget(panx_anim, pan); Storyboard.SetTargetProperty(panx_anim, new PropertyPath("X"));
DoubleAnimation pany_anim = new DoubleAnimation() { To = pany, Duration = duration, EasingFunction = func }; Storyboard.SetTarget(pany_anim, pan); Storyboard.SetTargetProperty(pany_anim, new PropertyPath("Y"));
sb.Children.Add(zoomx_anim); sb.Children.Add(zoomy_anim); sb.Children.Add(panx_anim); sb.Children.Add(pany_anim); sb.Begin(); }
public double ZoomCache { get { if (((UIElement)Content).CacheMode == null) return 0; else return ((BitmapCache)((UIElement)Content).CacheMode).RenderAtScale; } set { if (value == 0) ((UIElement)Content).CacheMode = null; else ((UIElement)Content).CacheMode = new BitmapCache() { RenderAtScale = value }; } } public double ZoomMargin { get; set; } } October 10 CollectionFlowCollectionFlow is a Carousel, CoverFlow, whatever (change it properties and get what you want) for Microsoft Silverlight 3.0. Unlike other samples, CollectionFlow inherit from ItemsControl, then you can use DataBinding / DataTemplate and change ItemsPanel (CollectionFlowPanel) properties. Updated (11Oct2009):
Updated (13Oct2009):
June 21 User eXperience KitUXKit (source code + samples + extras) is a small library with basic elements to archive a better user experience on Microsoft Silverlight 3.0 applications.
The three fundamental concepts in user experiences:
Features:
Note: A few util code (included in assembly) was obtained from some SL communities.
January 25 Silverlight Motion eXtensionsExtension methods to extend any Silverlight FrameworkElement. With Motion eXtensions you can compose animations/behaviors using the "Builder pattern", writing short and simple code.
Extensions:
// Overview, download link at end of post
public static class MotionExtensions {
public static void MotionEnable(this FrameworkElement source)
public static FrameworkElement Sleep(this FrameworkElement source, double duration);
public static FrameworkElement Add(this FrameworkElement source, Panel panel); public static FrameworkElement Remove(this FrameworkElement source);
public static FrameworkElement Show(this FrameworkElement source); public static FrameworkElement Hide(this FrameworkElement source);
public static FrameworkElement Fade(this FrameworkElement source, double opacity, double duration); public static FrameworkElement Fade(this FrameworkElement source, double opacity, double duration, double acceleration, double deceleration);
public static FrameworkElement Move(this FrameworkElement source, double x, double y, double duration); public static FrameworkElement Move(this FrameworkElement source, double x, double y, double duration, double acceleration, double deceleration);
public static FrameworkElement Zoom(this FrameworkElement source, double scale, double duration); public static FrameworkElement Zoom(this FrameworkElement source, double scale, double duration, double acceleration, double deceleration);
public static FrameworkElement Spin(this FrameworkElement source, double angle, double duration); public static FrameworkElement Spin(this FrameworkElement source, double angle, double duration, double acceleration, double deceleration);
public static FrameworkElement Push(this FrameworkElement source, double x, double duration); public static FrameworkElement Push(this FrameworkElement source, double x, double duration, double acceleration, double deceleration);
public static FrameworkElement Slice(this FrameworkElement source, double y, double duration); public static FrameworkElement Slice(this FrameworkElement source, double y, double duration, double acceleration, double deceleration);
public static FrameworkElement FlipH(this FrameworkElement source, double scale, double duration); public static FrameworkElement FlipH(this FrameworkElement source, double scale, double duration, double acceleration, double deceleration);
public static FrameworkElement FlipV(this FrameworkElement source, double scale, double duration); public static FrameworkElement FlipV(this FrameworkElement source, double scale, double duration, double acceleration, double deceleration);
public static FrameworkElement Action(this FrameworkElement source, ActionHandler function);
public static void Begin(this FrameworkElement source);
public static void SetOpacity(this FrameworkElement source, double opacity); public static double GetOpacity(this FrameworkElement source); public static void SetTranslation(this FrameworkElement source, double x, double y); public static Point GetTranslation(this FrameworkElement source); public static void SetRotation(this FrameworkElement source, double angle); public static double GetRotation(this FrameworkElement source); public static void SetScale(this FrameworkElement source, double sx, double sy); public static Size GetScale(this FrameworkElement source); } Samples:
// Sample 1 Rectangle rect = new Rectangle(); rect.Fill = new SolidColorBrush(Color.FromArgb(128, 255, 0, 0)); rect.Width = 100; rect.Height = 100;
rect.MotionEnable(); rect.SetTranslation(100, 100);
rect.Add(MyPanel).Spin(90, 0.5).Move(200, 200, 0.25).Zoom(2, 0.25).Remove().Begin(); rect.Sleep(0.75).Fade(0.0, 0.25).Begin();
// Sample 2 this.FlipH(0, 0.25).Action(MyAction).FlipH(1, 0.25).Begin();
void MyAction(FrameworkElement element) { // Change element }
// Sample 3 this.Push(-50, 0.25, 0.0, 0.5).Push(200, 0.25, 0.5, 0.0).Remove().Begin(); Notes:
January 03 HTML Helpers based on DCBWebsite base structure HTML Helpers for ASP.NET or ASP.NET MVC.
Note: Behaviors requires jQuery, Microsoft is looking to make it part of their official development platform.
January 01 Introducing Design-Content-Behavior (DCB)Design-Content-Behavior (DCB) is an architectural software pattern to split "View" of Model-View-Controller (MVC) in three layers.
This architecture isolates the fundamental areas of “User Experience". Design March 18 Silverlight LayersLooking for Bevel, Glow, Shadow, Reflection and Blur effects for Silverlight?! Not the perfect solution but you can do some Photoshop like effects on Silverlight by using pure vector graphics.
You can compose, adjust parameters and.. also modify source code to your needs. Includes:
Compose Notes:
Developed for Silverlight 2. Download Here March 02 Unreleased ProjectsYou can download some unreleased projects and some GotDotNet (closed) projects on my Public Folder.
Includes:
October 06 XAML CoverFlow Layout (Part III)This example show how to make an iTunes like "CoverFlow" layout animation in XAML (Silverlight/WPF). Code samples don't show reflection of elements. You can make it easily with a copy of CoverFlow canvas (with some transformations and opacity). Don't make reflection of each element.. Make reflection of whole "list" to do a correct reflection. Silverlight Coverflow sample (Download): XAML CoverFlow Layout (Part II)This example show how to make an iTunes like "CoverFlow" layout animation in XAML (Silverlight/WPF). Notes: · This was written to WPF, can easily converted to Silverlight! · Underline values are width of element · You can set animation duration and perspective of elements · Perspective value and height of element are related CoverFlow Layout (C#) private void SelectCover(int index) { // Setup double coverwidth = 100; double coverwidth2 = coverwidth / 2; double center = (coverflowcontrol.ActualWidth - coverwidth) / 2;
double perspectivetop = 25; double perspectivebotton = 10; double scaley = 0.8; double scalex = scaley * (1.0 - perspectivetop / coverwidth); double offset = coverwidth * 0.8;
// Layout for (int i = 0; i < coverflowcontrol.Children.Count; i++) { Canvas cover = (Canvas)coverflowcontrol.Children[i];
if (i < index) { Canvas.SetZIndex(cover, i);
Storyboard sb = (Storyboard)cover.Resources[cover.Name + "_anim"]; ((DoubleAnimation)sb.Children[0]).To = scalex; ((DoubleAnimation)sb.Children[1]).To = scaley; ((DoubleAnimation)sb.Children[2]).To = -perspectivebotton; ((DoubleAnimation)sb.Children[3]).To = center - (offset + ((index - 1) - i) * coverwidth2); ((PointAnimation)sb.Children[4]).To = new Point(0, 0); ((PointAnimation)sb.Children[5]).To = new Point(coverwidth, perspectivetop); sb.Begin(cover); } else if (i > index) { int ii = (i - index - 1);
Canvas.SetZIndex(cover, (coverflowcontrol.Children.Count - 1) - ii);
Storyboard sb = (Storyboard)cover.Resources[cover.Name + "_anim"]; ((DoubleAnimation)sb.Children[0]).To = scalex; ((DoubleAnimation)sb.Children[1]).To = scaley; ((DoubleAnimation)sb.Children[2]).To = perspectivebotton; ((DoubleAnimation)sb.Children[3]).To = center + (offset + ii * coverwidth2); ((PointAnimation)sb.Children[4]).To = new Point(0, perspectivetop); ((PointAnimation)sb.Children[5]).To = new Point(coverwidth, 0); sb.Begin(cover); } else { Canvas.SetZIndex(cover, coverflowcontrol.Children.Count);
Storyboard sb = (Storyboard)cover.Resources[cover.Name + "_anim"]; ((DoubleAnimation)sb.Children[0]).To = 1; ((DoubleAnimation)sb.Children[1]).To = 1; ((DoubleAnimation)sb.Children[2]).To = 0; ((DoubleAnimation)sb.Children[3]).To = center; ((PointAnimation)sb.Children[4]).To = new Point(0, 0); ((PointAnimation)sb.Children[5]).To = new Point(coverwidth, 0); sb.Begin(cover); } } } XAML CoverFlow Layout (Part I)This example show how to make an iTunes like "CoverFlow" layout animation in XAML (Silverlight/WPF).
Notes:
· This was written to WPF, can easily convert to Silverlight!
· Underline values are width of element
· You can set animation duration and perspective of elements
· Perspective value and height of element are related
Cover Element (XAML) <!--CoverFlow Control (List)--> <Canvas Name="coverflowcontrol"> (...) <!--CoverFlow Element--> <Canvas Name="coverXPTO" RenderTransformOrigin="0.5,0.5" Width="100" Height="100" Background="Black"> <Canvas.Resources> <Storyboard x:Key="coverXPTO_anim"> <DoubleAnimation To="1" Duration="0:0:0.2" Storyboard.TargetName="coverXPTO" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" /> <DoubleAnimation To="1" Duration="0:0:0.2" Storyboard.TargetName="coverXPTO" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" /> <DoubleAnimation To="0" Duration="0:0:0.2" Storyboard.TargetName="coverXPTO" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleY)" /> <DoubleAnimation To="0" Duration="0:0:0.2" Storyboard.TargetName="coverXPTO" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(TranslateTransform.X)" /> <PointAnimation To="0,0" Duration="0:0:0.2" Storyboard.TargetName="coverXPTO" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[0].(PathFigure.Segments)[0].(LineSegment.Point)" /> <PointAnimation To="100,0" Duration="0:0:0.2" Storyboard.TargetName="coverXPTO" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[0].(PathFigure.Segments)[1].(LineSegment.Point)" /> </Storyboard> </Canvas.Resources> <Canvas.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1" /> <SkewTransform AngleX="0" AngleY="0" /> <TranslateTransform X="0" Y="0" /> </TransformGroup> </Canvas.RenderTransform> <Canvas.Clip> <PathGeometry> <PathFigure StartPoint="0,100" IsClosed="True"> <PathFigure.Segments> <LineSegment Point="0,0"/> <LineSegment Point="100,0"/> <LineSegment Point="100,100"/> </PathFigure.Segments> </PathFigure> </PathGeometry> </Canvas.Clip> <!--Child Elements (Image, Text, etc...)--> </Canvas> (...) </Canvas> |
|
|