Search code examples
c#wpfcaliburn.micro

run a function of an ItemsControl item in MVVM from XAML


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


Solution

  • 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; }
        }
    }