Witam,
piszę aplikacje w WPF, staram się używać MVVM. Nie mogę zbindować pozycji kontrolki w canvasie z polami w ViewModelu. Zaimplementowałem również Behavior dla przesuwania kontrolek po ekranie, jednak po przesuniesiu wracają one na początkową pozycję, nie jestem pewien czy jest to spowodowane tym bindowaniem, bo kiedy używam MouseDragBehavior dodanego z Blenda controlki pozostają tam gdzie je zostawiłem. Jest coś co przeoczyłem, zapomniałem?
XAML:
<ItemsControl MinHeight="5000" MinWidth="5000" Width="Auto" Height="Auto" Margin="5" HorizontalAlignment="Center" VerticalAlignment="Center"
ItemsSource="{Binding Blocks}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type viewModels:BlockViewModel}">
<local:Block/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas ClipToBounds="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>
BlockViewModel:
public class BlockViewModel: ViewModelBase
{
public BlockViewModel()
{
Points = new PointCollection()
{
new Point(0, 0),
new Point(30, 0),
new Point(40, 20),
new Point(10, 20),
};
MouseDownCommand = new RelayCommand<MouseButtonEventArgs>(MouseDown);
}
public RelayCommand<MouseButtonEventArgs> MouseDownCommand { get; }
public void MouseDown(MouseButtonEventArgs obj)
{
Console.WriteLine($"{X} {Y}");
}
public PointCollection Points { get; private set; }
private double _x = 0;
public double X
{
get => _x;
set
{
if (_x == value)
return;
_x = value;
RaisePropertyChanged("X");
}
}
private double _y = 0;
public double Y
{
get => _y;
set
{
if (_y == value)
return;
_y = value;
RaisePropertyChanged("Y");
}
}
}
DragBehavior:
public class DragBehavior : Behavior<UIElement>
{
private Point elementStartPosition;
private Point mouseStartPosition;
private TranslateTransform transform = new TranslateTransform();
protected override void OnAttached()
{
Window parent = Application.Current.MainWindow;
AssociatedObject.RenderTransform = transform;
AssociatedObject.MouseLeftButtonDown += (sender, e) =>
{
elementStartPosition = AssociatedObject.TranslatePoint(new Point(), parent);
mouseStartPosition = e.GetPosition(parent);
AssociatedObject.CaptureMouse();
};
AssociatedObject.MouseLeftButtonUp += (sender, e) =>
{
AssociatedObject.ReleaseMouseCapture();
};
AssociatedObject.MouseMove += (sender, e) =>
{
Vector diff = e.GetPosition(parent) - mouseStartPosition;
if (AssociatedObject.IsMouseCaptured)
{
transform.X = diff.X;
transform.Y = diff.Y;
}
};
}
}