Как получить объект из ItemsControl по нажатию на него WPF

У меня есть поле для рисования, вот его код на xaml:

<Grid Grid.Column="1">
                <Rectangle Fill="Beige" MouseLeftButtonDown="Rectangle_MouseLeftButtonDown"/>
                <ItemsControl ItemsSource="{Binding Vertices}">
                    <ItemsControl.InputBindings>
                        <MouseBinding Gesture="LeftClick" Command="{Binding ClickOnVertex}"/>
                    </ItemsControl.InputBindings>
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <Canvas/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ItemsControl.ItemContainerStyle>
                        <Style>
                            <Setter Property="Canvas.Left" Value="{Binding X}"/>
                            <Setter Property="Canvas.Top" Value="{Binding Y}"/>
                        </Style>
                    </ItemsControl.ItemContainerStyle>
                    <ItemsControl.ItemTemplate>
                        <DataTemplate >
                            <Ellipse Width="20" Height="20" Fill="Black"/>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </Grid>

Это поле по шаблону отображает объекты VisualVertex из наблюдаемой коллекции Vertices.

Что мне передать в CommandParameter, чтоб в методе ClickOnVertex я получит объект, на который нажал

Код класса VisualVertex:

    public class VisualVertex: INotifyPropertyChanged
    {
        #region fields
        /// <summary>
        /// Вершина.
        /// </summary>
        private Vertex _vertex;

        /// <summary>
        /// Цвет.
        /// </summary>
        private Brush _color;
        #endregion

        #region properties
        /// <summary>
        /// Вершина.
        /// </summary>
        public Vertex Vertex
        {
            get
            {
                return _vertex;
            }
            private set
            {
                if (value == null)
                {
                    throw new ArgumentNullException(nameof(value), "Пустая вершина.");
                }

                _vertex = value;
            }
        }

        /// <summary>
        /// Ширина.
        /// </summary>
        public int Width { get; set; }

        /// <summary>
        /// Высота.
        /// </summary>
        public int Height { get; set; }

        /// <summary>
        /// Коориднаты.
        /// </summary>
        public (double, double) Coordinates
        {
            get
            {
                return _vertex.Сoordinates;
            }
            set
            {
                _vertex.Сoordinates = value;
                OnPropertyChanged(nameof(Coordinates));
            }
        }

        public double X
        {
            get
            {
                return _vertex.Сoordinates.Item1;
            }
        }

        public double Y
        {
            get
            {
                return _vertex.Сoordinates.Item2;
            }
        }

        /// <summary>
        /// Номер.
        /// </summary>
        public int Number
        {
            get
            {
                return _vertex.Number;
            }
            set
            {
                _vertex.Number = value;
                OnPropertyChanged(nameof(Number));
            }
        }

        /// <summary>
        /// Название.
        /// </summary>
        public string Name
        {
            get
            {
                return _vertex.Name;
            }
            set
            {
                _vertex.Name = value;
                OnPropertyChanged(nameof(Name));
            }
        }

        /// <summary>
        /// Цвет.
        /// </summary>
        public Brush Color
        {
            get
            {
                return _color;
            }
            set
            {
                if (value == null)
                {
                    throw new ArgumentNullException(nameof(value), "Пустой цвет.");
                }

                _color = value;
                OnPropertyChanged(nameof(Color));
            }
        }

        public event PropertyChangedEventHandler? PropertyChanged;
        #endregion

        #region constructors
        /// <summary>
        /// Конструктор.
        /// </summary>
        /// <param name="x">X координата.</param>
        /// <param name="y">Y координата.</param>
        /// <param name="number">Номер вершины.</param>
        /// <param name="color">Цвет.</param>
        /// <param name="name">Название.</param>
        public VisualVertex(double x, double y, int number, Color color, string name = "default")
        {
            _vertex = new Vertex(x, y , number, name);
            Color = new SolidColorBrush(color);
        }

        /// <summary>
        /// Конструктор.
        /// </summary>
        /// <param name="coordinates">Координаты.</param>
        /// <param name="number">Номер вершины.</param>
        /// <param name="color">Цвет.</param>
        /// <param name="name">Название.</param>
        public VisualVertex((double, double) coordinates, int number, Color color, string name = "default")
        {
            _vertex = new Vertex(coordinates, number, name);
            Color = new SolidColorBrush(color);
        }
        #endregion

        #region private methods
        private void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    }

Код ViewModel

public class MainWindowViewModel
    {
        #region fields
        /// <summary>
        /// Команда изменения режима мыши.
        /// </summary>
        private RelayCommand _changeMouseMode;

        /// <summary>
        /// Команда добавыления вершины.
        /// </summary>
        private RelayCommand _clickOnField;

        /// <summary>
        /// Команда нажатия на вершину.
        /// </summary>
        private RelayCommand _clickOnVertex;

        /// <summary>
        /// Режим мыши.
        /// </summary>
        private static MouseMode _mouseMode;
        #endregion


        #region properties
        /// <summary>
        /// Свойство команды изменения режима мыши.
        /// </summary>
        public RelayCommand ChangeMouseMode
        {
            get
            {
                return _changeMouseMode;
            }
            set
            {
                if (value == null)
                {
                    throw new ArgumentNullException(nameof(value), "Команда является пустой.");
                }

                _changeMouseMode = value;
            }
        }

        /// <summary>
        /// Команда добавления вершины.
        /// </summary>
        public RelayCommand ClickOnField
        {
            get
            {
                return _clickOnField;
            }
            set
            {
                if (value == null)
                {
                    throw new ArgumentNullException(nameof(value), "Пустая команда нажатия на поле.");
                }

                _clickOnField = value;
            }
        }

        /// <summary>
        /// Команда нажатия на вершину.
        /// </summary>
        public RelayCommand ClickOnVertex
        {
            get
            {
                return _clickOnVertex;
            }
            set
            {
                if (value == null)
                {
                    throw new ArgumentNullException(nameof(value), "Пустая команда нажатия на вершину.");
                }

                _clickOnVertex = value;
            }
        }

        public VisualVertex SelectedVertex { get; set; }

        /// <summary>
        /// Лист вершин.
        /// </summary>
        public ObservableCollection<VisualVertex> Vertices { get; set; }
        #endregion

        #region constructor
        /// <summary>
        /// Конструктор.
        /// </summary>
        public MainWindowViewModel()
        {
            Vertices = new ObservableCollection<VisualVertex>();

            ChangeMouseMode = new RelayCommand(SetMouseMode);
            ClickOnField = new RelayCommand(ClickOnFieldCommand);
            ClickOnVertex = new RelayCommand(ClickOnVertexCommand);
        }
        #endregion


        #region public methods
        #endregion


        #region private methods
        /// <summary>
        /// Изменение режима мыши.
        /// </summary>
        /// <param name="mode">Режим мыши.</param>
        private void SetMouseMode(object mode)
        {
            _mouseMode = (MouseMode)mode;
        }

        /// <summary>
        /// Команда нажатия на поле.
        /// </summary>
        /// <param name="parameter">Параметр.</param>
        private void ClickOnFieldCommand(object parameter)
        {
            if (_mouseMode == MouseMode.Create)
            {
                AddVertexCommand((Point)parameter);
            }
        }


        private void ClickOnVertexCommand(object parameter)
        {
            
        }

        /// <summary>
        /// Добавление новой вершины.
        /// </summary>
        /// <param name="parameter">Координаты верпшины.</param>
        private void AddVertexCommand(Point point)
        {
            Vertices.Add(new VisualVertex(
                (point.X, point.Y),
                Vertices.Count + 1,
                Colors.Black
            ));
        }
        #endregion

    }

Ответы (1 шт):

Автор решения: zarnii

Не знаю на сколько это правильно, но я решил свою проблему с помощью Interaction.Triggers

Через NuGet добавил пакет Microsoft.Xaml.Behaviors.Wpf

В DataTemplate поменял код на следующий

<Ellipse Width="20" Height="20" Fill="Black">
   <i:Interaction.Triggers>
      <i:EventTrigger EventName="PreviewMouseDown">
            <i:InvokeCommandAction Command="{Binding Path=DataContext.ClickOnVertex, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" CommandParameter="{Binding}"/>
      </i:EventTrigger>
    </i:Interaction.Triggers>
</Ellipse>

И теперь в метод параметром прилетает тот VisualVertex, на который я нажал.

→ Ссылка