0

Необходимо, чтобы при изменении координаты линии свойство передовалось во ViewModel (координаты линии изменяются при перемещении курсора).

MainWindow.xaml <Canvas Name="test" Background="Transparent" MouseMove="test_MouseMove"></Canvas> MainWindow.xaml.cs

public partial class MainWindow : Window
    {
        private Line line;
        public MainWindow()
        {
            InitializeComponent();
            line = new Line
            {
                Stroke = Brushes.Black,
                StrokeThickness = 1,
                X1 = 100,
                Y1 = 0,
            };
            test.Children.Add(line);
            var viewModel = new ViewModel();
            var myBinding = new Binding
            {
                Source = viewModel,
                Path = new PropertyPath("X2"),
                UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
            };
            BindingOperations.SetBinding(line, Line.X2Property, myBinding);
        }
    private void test_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
    {
        var point = e.GetPosition(this);
        line.X2 = point.X;
        line.Y2 = point.Y;
    }
}

ViewModel

internal class ViewModel
{
    private double x2;
    public double X2 
    { 
        get
        { 
            return x2; 
        }
        set
        {
            x2 = value;
        }
    }
}

  • Ужасный код, нарушающий все возможные правила. Если вы делаете по принципам MVVM, то у вас его нет. 1. View не должна знать ничего про VM и M слои, а у вас прям создается в окне (View слое) класс ViewModel, вынесите это за пределы окна и подключите к окну как DataContext, не нужно ничего городить больше. 2. Ни в коем случае не создавайте и не управляйте элементами View через код, у вас для этого есть XAML, в котором все это и указывается. Вот этого test.Children.Add(line); вообще быть не должно. 3. Привязка аналогично, в XAML сделали {Binding свойство} и все, не надо в коде. – EvgeniyZ Aug 03 '23 at 17:50
  • У вас должно быть что-то типа этого, любую фигуру так прописывайте и реализовывайте ей любое поведение, ну и окну задаете DataContext, все, почти ни единой строки C# кода... – EvgeniyZ Aug 03 '23 at 17:53
  • Вроде View может знать про ViewModel, так как при присваивании к DataContext ViewModel, View уже про него знает, а вот ViewModel ничего не должен знать про View. 2. Если у меня линии создаются во время выполнения (например какой-нибудь редактор блок-схем) тот test.Children.Add(line) необходим. Мне необходимо сделать привязку через код c#.
  • – thebrokenblow Aug 03 '23 at 18:26
  • Вы не поняли о чем я. Вот условно class MainWindow { public MainWindow() { DataContext = new VM(); } } или var window = new MainWindow { DataContext = new VM() }, два способа установки свойства, где в первом случае окно даже и не скомпилируется, если удалить класс VM, а в другом случае, мы снаружи устанавливаем это свойство, и о нем знает только внешний класс, не View. Почитайте ссылку, которую я дал выше. 2. "необходим" - ошибаетесь, я вам также дал ссылку, где я хоть одну строку C# там написал? Вы такого не найдете, но на экране у меня вдруг 4 круга, как? Внимание на ItemsControl.
  • – EvgeniyZ Aug 03 '23 at 18:41
  • Спасибо, разобрался, так действительно лучше. – thebrokenblow Aug 04 '23 at 07:08
  • А подскажи пожалуйста как теперь обратиться к canvas если я хочу сохранить изображение (png) фигур на нём.

    <ItemsControl.ItemsPanel> </ItemsControl.ItemsPanel>

    https://stackoverflow.com/questions/8881865/saving-a-wpf-canvas-as-an-image как в данном примере

    – thebrokenblow Sep 17 '23 at 16:17
  • Отдельный вопрос задайте. – EvgeniyZ Sep 17 '23 at 17:10
  • https://ru.stackoverflow.com/questions/1541235/%D0%9D%D0%B5%D0%BE%D0%B1%D1%85%D0%BE%D0%B4%D0%B8%D0%BC%D0%BE-%D1%84-%D1%84%D0%BE%D1%82%D0%BE%D0%B3%D1%80%D0%B0%D1%84%D0%B8%D1%8E-img-%D0%BA%D0%B0%D0%BD%D0%B2%D0%B0%D1%81%D0%B0-wpf-c – thebrokenblow Sep 17 '23 at 22:29