run a function of an ItemsControl item in MVVM from XAML

53 Views Asked by At

I'm doing a simple app in C# WPF using Caliburn.Micro for MVVM

I want to execute a function of an ItemsControl item, but I get the next exception when clicking a Rectangle

System.Exception: 'No target found for method ChangeColor.'

Here is the XAML code

<ItemsControl ItemsSource="{Binding Lines}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas Background="LightYellow" Margin="10 0" Width="{Binding CanvasWidth}" Height="{Binding CanvasHeight}" Focusable="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>
            <Rectangle Width="{Binding Width}"
                       Height="{Binding Height}"
                       Stroke="Black" StrokeThickness="1"
                       Fill="Black"
                       cal:Message.Attach="[Event MouseDown] = [Action ChangeColor()]"
            />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

The ItemsSource is an ObservableCollection that contains an object that I created that only has a couple variables like the bound in the Rectangle element, and the ChangeColor function

I suppose that it has something to do with the current context, but I can't understand why, when the bound variables Width and Height are working just fine although they are in the same object as the ChangeColor function

1

There are 1 best solutions below

2
Frenchy On BEST ANSWER

The only thing i see is a bad definition of your Method.

i hace tested and no problem, this is the code i have tested: in MainViewModel.cs

using Caliburn.Micro;
using System.Collections.Generic;
using System.Windows.Media;
using System.Windows.Shapes;

namespace UserControlSample.ViewModels
{
    public class MainViewModel : Screen
    {
        public BindableCollection<Lines> Lines { get; set; }
        private int canvasWidth;
        public int CanvasWidth
        {
            get { return canvasWidth; }
            set
            {
                canvasWidth = value;
                NotifyOfPropertyChange(() => CanvasWidth);
            }
        }
        private int canvasHeight;
        public int CanvasHeight
        {
            get { return canvasHeight; }
            set
            {
                canvasHeight = value;
                NotifyOfPropertyChange(() => CanvasHeight);
            }
        }

        public MainViewModel()
        {
            var a = new List<Lines>()
            {
                new Lines {X = 20, Y = 20, Width = 400, Height = 50}
            };
            canvasWidth = 500;
            canvasHeight = 300;
            Lines = new BindableCollection<Lines>(a);
            FileNames = new BindableCollection<string>() { "Test1", "test2" };
        }

        public void ChangeColor(Rectangle sender)
        {
            SolidColorBrush color = new SolidColorBrush(Colors.AliceBlue);
            sender.Fill = color;
        }
    }
}

The method defined in xaml:

cal:Message.Attach="[Event MouseDown] = [Action ChangeColor($source)]"

and the class Lines:

namespace UserControlSample.ViewModels
{
    public class Lines
    {
        public int X { get; set; }
        public int Y { get; set; }
        public int Width { get; set; }
        public int Height { get; set; }
    }
}