Search code examples
menuitemcaliburn.micro

Using Caliburn.Micro cal:Message.Attach does a No target found for method


I have created dynamic MenuItems with the last recent open folders. This works well. Now, beacause these MenuItems are created dynamically, when I click on one MenutItem, I would like to raise an action and give the header of the MenuItem as a parameter. So this is my "MainView.xaml"

        <Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
    xmlns:common="clr-namespace:Common;assembly=RecentFileListLib" 
    xmlns:cal="http://www.caliburnproject.org" 
    xmlns:self="clr-namespace:MainUI.Models"
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    xmlns:ViewModels="clr-namespace:MainUI.ViewModels" xmlns:local="clr-namespace:MainUI.Views" x:Name="window" x:Class="MainUI.Views.MainView"
    mc:Ignorable="d"
    Title="MainView" Height="450" Width="800">
<Window.Resources>
    <self:DebugDummyConverter x:Key="DebugDummyConverter" />
</Window.Resources>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="20"/>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="20"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="20"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="20"/>
    </Grid.RowDefinitions>
    <Menu Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="4" Margin="0">
        <MenuItem x:Name="menuItem"   Header="_File">
            <MenuItem Header="_Open" x:Name="FileOpen"/>

            <MenuItem x:Name="RecentProject" Header="Recents Projects" >
                <MenuItem.ItemTemplate   >
                    <DataTemplate >
                        <MenuItem Header="{Binding DisplayPath, Converter={StaticResource DebugDummyConverter}}" cal:Message.Attach="Remove($dataContext)"/>
                    </DataTemplate>
                </MenuItem.ItemTemplate>

            </MenuItem>
        </MenuItem>
    </Menu>
    <StackPanel Orientation="Vertical" Grid.Row="2" Grid.Column="1" Grid.RowSpan="1" Margin=" 0 0 10 0" >
        <Button x:Name="LoadUser" Content="Load User Page" />

    </StackPanel>
    <ContentControl Grid.Row="1" Grid.Column="2" Grid.ColumnSpan="1" Grid.RowSpan="2" x:Name="ActiveItem"/>
    <StatusBar Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="2">
        <StatusBar.ItemsPanel>
            <ItemsPanelTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="100" />
                    </Grid.ColumnDefinitions>
                </Grid>
            </ItemsPanelTemplate>
        </StatusBar.ItemsPanel>
        <StatusBarItem Grid.Column="1">
            <TextBlock Text="{Binding FolderPath}" />
        </StatusBarItem>
    </StatusBar>
</Grid>

For this I'm using cal:Message.Attach="Remove($dataContext) And in my view model "MainViewModel"

public partial class MainViewModel : Conductor<Object>
{

    public BindableCollection<RecentFile> RecentProject { get; private set; } = new BindableCollection<RecentFile>();

    public string FolderPath { get; set; }


    public MainViewModel()
    {
        Persister = new RegistryPersister();

        MaxNumberOfFiles = 9;
        MaxPathLength = 50;
        MenuItemFormatOneToNine = "_{0}:  {2}";
        MenuItemFormatTenPlus = "{0}:  {2}";
        RemoveMenuItems();
        LoadRecentFiles();
    }

    public void Remove(Object child)
    {

    }

By doing it like this, when I click on my menuitem I have a message "No target found for method Remove."

If someone can help me.

Thanks in advance


Solution

  • You could make use of cal:Action:TargetWithoutContext. For example,

    cal:Action.TargetWithoutContext="{Binding ElementName=RecentProject, Path=DataContext}"
    

    Complete Code

    <MenuItem x:Name="RecentProject" Header="Recents Projects" Tag="{Binding}">
                        <MenuItem.ItemTemplate   >
                            <DataTemplate >
                                <MenuItem Header="{Binding DisplayPath}" cal:Message.Attach="Remove($dataContext)" cal:Action.TargetWithoutContext="{Binding ElementName=RecentProject, Path=DataContext}"/>
                            </DataTemplate>
                        </MenuItem.ItemTemplate>
    </MenuItem>