0

Мой UserControl:

public class ElementViewModel : ViewModelBase
{
    public ElementViewModel() { }

    public double X { get; set; }
    public double Y { get; set; }



    public Command<ElementViewModel> OnMouseDown => new Command<ElementViewModel>((elem) =>
    {
        // ???
    });

    public Command<ElementViewModel> OnMouseMove => new Command<ElementViewModel>((elem) =>
    {
        // ???
    });

    public Command<ElementViewModel> OnMouseUp => new Command<ElementViewModel>((elem) =>
    {
        // ???
    });

    protected override async Task InitializeAsync() 
        => await base.InitializeAsync();
    protected override async Task CloseAsync() => 
        await base.CloseAsync();
}

MainWindow View:

<ItemsControl ItemsSource="{Binding Elements}">
    <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>
            <views:Element>
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="MouseDown">
                        <i:InvokeCommandAction Command="{Binding OnMouseDown}" 
                                                   CommandParameter="{Binding}"/>
                    </i:EventTrigger>
                    <i:EventTrigger EventName="MouseMove">
                        <i:InvokeCommandAction Command="{Binding OnMouseMove}"
                                                   CommandParameter="{Binding}"/>
                    </i:EventTrigger>
                    <i:EventTrigger EventName="MouseUp">
                        <i:InvokeCommandAction Command="{Binding OnMouseUp}"
                                                   CommandParameter="{Binding}"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </views:Element>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

И MainWindow ViewModel:

public class MainWindowViewModel : ViewModelBase
{
    public MainWindowViewModel()
    {
        Elements.Add(new ElementViewModel());
        Elements.Add(new ElementViewModel());
    }

    public ObservableCollection<ElementViewModel> Elements { get; set; }
        = new ObservableCollection<ElementViewModel>();


    protected override async Task InitializeAsync() 
        => await base.InitializeAsync();
    protected override async Task CloseAsync() 
        => await base.CloseAsync();
}

Хочу реализовать перетягивание мышкой свой ElementViewMode по ItemsControl. Как это сделать без парамеротров из EventArgs? Или как получить эти параметры в Command? Перепробывал много вариантов из инета, все либо без MVVM либо не работают(может плохо искал, тогда дайте ссылку). Пользуюсь Catel. Решения без Catel тоже должно подойти, главное чтоб MVVM соблюдался.

P.S. Пользуюсь ещо и Fody так что все свойства на самом деле PropertyChanged

2 Answers2

0

Если вариант с получением EventArgs во ViewModel приемлемый, то в Catel можно использовать EventToCommand

<Commands:EventToCommand Command="{Binding Edit}" DisableAssociatedObjectOnCannotExecute="False" PassEventArgsToCommand="True" />
-1

Можно попробовать (да, конечно, это только кателовское решение) привесить этот behavior: https://docs.catelproject.com/5.0/reference/catel.mvvm/catel/windows/interactivity/dragdrop на ItemControl и слушать событие ObservableCollection.CollectionChanged во VM...все в рамках MVVM

P.S. я не очень уверен тоже, что использовать Command Binding на MouseMove хорошая идея... но, например, чтобы не "загрязнять" VM аргументами событий из EventToCommand (https://catelproject.atlassian.net/wiki/spaces/CTL/pages/1409072/EventToCommand) можно использовать конвертер:

<catel:EventToCommand Command="{Binding MyCommand}" 
PassEventArgsToCommand="True" DisableAssociatedObjectOnCannotExecute="False"
EventArgsConverter="{StaticResource SomeArgsConverter}"/>