0

I'm making a tool where I can edit images, so I have a custom Control to draw on a canvas. For this control I bound the resolution and the color of the brush which work perfectly fine, but when I try to bind a Canvas I always get null in myViewModel.

I tried binding a List instead, but that didn't work either. I've been trying to figure out what the problem is for about 12 hours now so I think it's time to ask you guys for help so I can maybe figure out what's wrong.

I used to work with singletons for my viewmodels, and then I could link to the Canvas just fine, but then I realised this is a bad way of working so I tried to bind it with dependency properties.

Whenever I try to access the Canvas it has a value of null, even though I initialized it.

Control

    public static readonly DependencyProperty CanvasProperty = DependencyProperty.Register(
  "CanvasToDraw", typeof(Canvas), typeof(DrawCanvas), new PropertyMetadata(default(Canvas), null, null));

    public Canvas CanvasToDraw
    {
        get { return (Canvas)GetValue(CanvasProperty); }
        set { SetValue(CanvasProperty, value); }
    }

        public DrawCanvas()
    {
        InitializeComponent();
        CanvasToDraw = CanvasGrid;
    }

XAML

<Controls:DrawCanvas x:Name="DrawCanvas1" Resolution="{Binding Resolution}" CanvasToDraw="{Binding DrawingCanvas}" RectangleList="{Binding RectangleList, ElementName=DrawCanvas1}" ColorToDraw="{Binding SelectedColor}" HorizontalAlignment="Left" Height="256" Margin="10,40,0,0" VerticalAlignment="Top" Width="256" />

VIEWMODEL

        private Canvas _drawingCanvas;
    public Canvas DrawingCanvas
    {
        get { return _drawingCanvas; }
        set
        {
            _drawingCanvas = value;
            OnPropertyChanged("DrawingCanvas");
        }
    }

I can provide more code if needed, but this is most of the relevant code. And yes I do use INotifyPropertyChanged, since I have other things that I bound that do work.

  • As a note, you should not have UI elements (like your DrawingCanvas) in view models. Besides that, with "even though I initialized it" do you mean the assignment `CanvasToDraw = CanvasGrid;` in the DrawCanvas constructor? – Clemens Jan 05 '17 at 12:35
  • Yes, is that the correct way to do it? What would in your opinion be the best way to get the data from the canvas? The canvas exists out of Rectangles which are pixels in this case, and I need to access them to make them turn white when I press a button to "clean" the canvas. I tried binding the list of rectangles, but that didn't work either for some reason (Maybe I need to initialise it on a specific place or something) + The CanvasGrid is the name of the Canvas, I used to link this by using BlockViewModel.Instance.Canvas = CanvasGrid. But I stopped using instances. – user3678781 Jan 05 '17 at 12:45
  • You should use an ItemsControl with a Canvas as ItemsPanel, as e.g. shown [here](http://stackoverflow.com/a/22325266/1136211). Your initialization won't work because the value is replaced by the Binding. It returns `null` because the source property in the view model is `null`. The Binding must also be two-way. – Clemens Jan 05 '17 at 12:50
  • Ok, I'll look some stuff up about ItemsControl and try to figure out how to use this in my application, thanks for the help. – user3678781 Jan 05 '17 at 12:54

1 Answers1

0

I've been looking for a solution for so long, but the answer was so simple. I assumed the binding was two way, but appareantly I had to set Mode=TwoWay and everything worked like a charm. (Linking an observeablecollection, not a Canvas)