コンテナの型を指定したItemsControl継承クラス
StyleTypedPropertyAttributeとGetContainerForItemOverrideを実装すれば、とりあえずコンテナの型を指定したItemsControl継承クラスが作れるようです。
// StyleTypedPropertyAttributeを指定する
[StyleTypedPropertyAttribute(Property = "ItemContainerStyle", StyleTargetType = typeof(AnimationCanvasItem))]
public class AnimationCanvas : ItemsControl
{
// ItemContainerとなるオブジェクトを生成して返す
protected override DependencyObject GetContainerForItemOverride()
{
return new AnimationCanvasItem();
}
}
なお、コンテナのクラスとXamlは以下のようなものを作りました。
public class AnimationCanvasItem : ContentControl
{
// 目標とするCanvas.Xの依存関係プロパティ
public static readonly DependencyProperty XProperty = DependencyProperty.Register("X", typeof(double), typeof(AnimationCanvasItem), new PropertyMetadata( (sender, e) =>
{
DoubleAnimation animation = new DoubleAnimation( (double)e.OldValue, (double)e.NewValue, new Duration(TimeSpan.FromMilliseconds(100)));
Storyboard.SetTarget(animation, (DependencyObject)sender);
Storyboard.SetTargetProperty(animation, new PropertyPath("(Canvas.Left)"));
var story = new Storyboard();
story.Children.Add(animation);
story.Begin();
}));
// 目標とするCanvas.Yの依存関係プロパティ
public static readonly DependencyProperty YProperty = DependencyProperty.Register("Y", typeof(double), typeof(AnimationCanvasItem), new PropertyMetadata( (sender, e) =>
{
DoubleAnimation animation = new DoubleAnimation( (double)e.OldValue, (double)e.NewValue, new Duration(TimeSpan.FromMilliseconds(100)));
Storyboard.SetTarget(animation, (DependencyObject)sender);
Storyboard.SetTargetProperty(animation, new PropertyPath("(Canvas.Top)"));
var story = new Storyboard();
story.Children.Add(animation);
story.Begin();
}));
// 目標とするCanvas.Xを取得または設定します
public double X
{
get { return (double)this.GetValue(AnimationCanvasItem.XProperty); }
set { this.SetValue(AnimationCanvasItem.XProperty, value); }
}
// 目標とするCanvas.Yを取得または設定します
public double Y
{
get { return (double)this.GetValue(AnimationCanvasItem.YProperty); }
set { this.SetValue(AnimationCanvasItem.YProperty, value); }
}
}
<contorls:AnimationCanvas ItemsSource="{Binding Items}">
<contorls:AnimationCanvas.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</contorls:AnimationCanvas.ItemsPanel>
<contorls:AnimationCanvas.ItemContainerStyle>
<Style TargetType="contorls:AnimationCanvasItem">
<Setter Property="X" Value="{Binding X, Converter={StaticResource ParameterTimesConverter}, ConverterParameter=32}"/>
<Setter Property="Y" Value="{Binding Y, Converter={StaticResource ParameterTimesConverter}, ConverterParameter=32}"/>
<Setter Property="Content">
<Setter.Value>
<Image Source="{Binding Image}" Stretch="None"/>
</Setter.Value>
</Setter>
</Style>
</contorls:AnimationCanvas.ItemContainerStyle>
</contorls:AnimationCanvas>
Canvas内の複数のコントロールを、移動するたびにアニメーションさせます。Microsoft Excel 2013 がいちいちアニメーションするようになっていたので、NanoBlockMakerでもやってみようと思ったのですが、鬱陶しいので見送りました。
アニメーションのCompletedをコマンド経由で通知したり、DurationやEasingFunctionをバインドできるようにすれば、ゲームなどを作るときに役に立つかもしれません。