Skip to content

Instantly share code, notes, and snippets.

@karno
Created December 12, 2010 04:05
Show Gist options
  • Save karno/737830 to your computer and use it in GitHub Desktop.
Save karno/737830 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace EroTool.View.UserCtl
{
/// <summary>
/// ImageStackView.xaml の相互作用ロジック
/// </summary>
public partial class ImageStackView : UserControl
{
public ImageStackView()
{
InitializeComponent();
this.DataContextChanged += new DependencyPropertyChangedEventHandler(ImageStackView_DataContextChanged);
}
private object intnLock = new object();
/// <summary>
/// アップデート チケット
/// </summary>
private long Ticket = 0;
void ImageStackView_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
UpdateUI();
}
public int MaxStackingCount
{
get { return (int)GetValue(MaxStackingCountProperty); }
set { SetValue(MaxStackingCountProperty, value); }
}
// Using a DependencyProperty as the backing store for MaxStackingCount. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MaxStackingCountProperty =
DependencyProperty.Register("MaxStackingCount", typeof(int), typeof(ImageStackView), new FrameworkPropertyMetadata(0, MaxStackingCountChanged));
private static void MaxStackingCountChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
RegenerateUI(o as ImageStackView);
}
public void UpdateUI()
{
RegenerateUI(this);
}
static void RegenerateUI(ImageStackView stk)
{
if (stk == null) return;
var ticket = System.Threading.Interlocked.Increment(ref stk.Ticket);
var sources = (stk.DataContext as IEnumerable<BitmapImage>);
stk.Stacker.Children.Clear();
if (sources == null) return;
var maxstk = stk.MaxStackingCount;
stk.LoadingAnimation.Visibility = Visibility.Visible;
var act = new Action(() =>
{
if (stk.Ticket != ticket) return;
var src = (from i in sources.Take(maxstk) select i).Reverse().ToList();
stk.Dispatcher.BeginInvoke(new Action(() =>
{
var lo = LayoutLogic(stk, src);
lock (stk.intnLock)
{
if (stk.Ticket != ticket) return;
UpdateUI(stk, lo);
}
}), null);
});
act.BeginInvoke((iar) => act.EndInvoke(iar), null);
}
static IEnumerable<UIElement> LayoutLogic(ImageStackView stk, List<BitmapImage> sources)
{
if (sources == null) yield break;
if (sources.Count == 0)
yield break;
// 0 - 90°にバラける
int ddeg = 90 / sources.Count;
int cdeg = ddeg * (sources.Count - 1);
foreach (var s in sources)
{
var img = new Image() { Source = s, Stretch = Stretch.Uniform };
img.Width = 100;
img.Height = 100;
var border = new Border() { BorderBrush = Brushes.Gainsboro, BorderThickness = new Thickness(1), Background = new SolidColorBrush(Color.FromArgb(120, 255, 255, 255)) };
border.LayoutTransform = new RotateTransform(cdeg);
border.Child = img;
yield return border;
cdeg -= ddeg;
}
}
static void UpdateUI(ImageStackView stk, IEnumerable<UIElement> lo)
{
foreach (var l in lo)
{
l.SetValue(Grid.HorizontalAlignmentProperty, HorizontalAlignment.Center);
l.SetValue(Grid.VerticalAlignmentProperty, VerticalAlignment.Center);
stk.Stacker.Children.Add(l);
}
stk.LoadingAnimation.Visibility = Visibility.Collapsed;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment