<Window x:Class="MiscSamples.ClickToMove"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ClickToMove" Height="300" Width="300">
<ItemsControl ItemsSource="{Binding}" PreviewMouseDown="ItemsControl_PreviewMouseDown"
Background="#05FFFFFF">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding X}"/>
<Setter Property="Canvas.Top" Value="{Binding Y}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Stroke="Black" StrokeThickness="2" Fill="Blue"
Height="20" Width="20"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Window>
コードビハインド:
public partial class ClickToMove : Window
{
public List<MovableObject> Objects { get; set; }
public ClickToMove()
{
InitializeComponent();
Objects = new List<MovableObject>
{
new MovableObject() {X = 100, Y = 100}
};
DataContext = Objects;
}
private void ItemsControl_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
var position = e.GetPosition(this);
Objects.First().MoveToPosition(position.X, position.Y);
}
}
ビューモデル:
public class MovableObject: INotifyPropertyChanged
{
private double _x;
public double X
{
get { return _x; }
set
{
_x = value;
OnPropertyChanged("X");
}
}
private double _y;
public double Y
{
get { return _y; }
set
{
_y = value;
OnPropertyChanged("Y");
}
}
private System.Threading.Timer MoveTimer;
private double DestinationX;
private double DestinationY;
public void MoveToPosition(double x, double y)
{
DestinationX = x;
DestinationY = y;
if (MoveTimer != null)
MoveTimer.Dispose();
MoveTimer = new Timer(o => MoveStep(), null, 0, 10);
}
private void MoveStep()
{
if (Math.Abs(X - DestinationX) > 5)
{
if (X < DestinationX)
X = X+5;
else if (X > DestinationX)
X = X-5;
}
if (Math.Abs(Y - DestinationY) > 5)
{
if (Y < DestinationY)
Y = Y + 5;
else if (Y > DestinationY)
Y = Y - 5;
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
Application.Current.Dispatcher.BeginInvoke((Action)(() =>
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}));
}
}