Событие щелчка по микротаблице Caliburn, цель для метода не найдена

#c# #wpf #mvvm #caliburn.micro #mahapps.metro

#c# #wpf #mvvm #caliburn.micro #mahapps.metro

Вопрос:

Я использую Caliburn Micro для вызова метода в моей ViewModel из элемента меню в моем представлении. Но каждый раз, когда я нажимаю на MenuItem, я получаю исключение: цель не найдена для метода SuggestPresent. Я пробовал разные способы вызова моего метода ViewModel, но пока ничего не получалось. Как я могу заставить это работать?

MainView.xaml

 <Controls:MetroWindow x:Class="Expreriment.Views.MainView"
    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:model="clr-namespace:Expreriment.ViewModels"
    xmlns:vc="clr-namespace:Expreriment.Converters"
    xmlns:local="clr-namespace:Expreriment"
    xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
    xmlns:cal="http://www.caliburnproject.org"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    mc:Ignorable="d"
    d:DataContext="{x:Type model:MainViewModel}"
    Title="{Binding WindowTitle}"
    x:Name="Window"
    Height="500" Width="800">

<Controls:MetroWindow.Resources>
    <vc:FindResourceFromString x:Key="FindResourceFromStringConverter" />
</Controls:MetroWindow.Resources>

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <Controls:Flyout Header="Menu" Position="Left" Width="175" IsOpen="True" Name="menuFlyout" Grid.Column="0">
        <Menu ItemsSource="{Binding enumData}" DisplayMemberPath="Enum">
            <Menu.ItemsPanel>
                <ItemsPanelTemplate>
                    <VirtualizingStackPanel Orientation="Vertical"/>
                </ItemsPanelTemplate>
            </Menu.ItemsPanel>
            <MenuItem Header="Category" ItemsSource="{Binding EnumData}" DisplayMemberPath="Enum">
                <MenuItem.ItemContainerStyle>
                    <Style TargetType="MenuItem">
                        <Setter Property="IsCheckable" Value="True"/>
                        <Setter Property="IsChecked" Value="{Binding IsChecked, Mode=TwoWay}"/>
                        <Setter Property="StaysOpenOnClick" Value="True"/>
                    </Style>
                </MenuItem.ItemContainerStyle>
            </MenuItem>
            <MenuItem cal:Action.TargetWithoutContext="{Binding ElementName=Window, Path=Datacontext}" cal:Message.Attach="SuggestPresent" Header="Suggest present">
                <MenuItem.Icon>
                    <Image Height="25" Width="25" Source="/Resources/Images/Plus.png"/>
                </MenuItem.Icon>
            </MenuItem>
        </Menu>
    </Controls:Flyout>

    <Controls:FlipView Grid.Column="1" ItemsSource="{Binding Gifts}" SelectedItem="{Binding Path=SelectedGift, Mode=TwoWay}" BannerText="{Binding SelectedGift.Name}">
        <Controls:FlipView.ItemTemplate>
            <DataTemplate>
                <Grid Background="#2E8DEF">
                    <Rectangle Margin="0, 0, 10, 0" Width="100" Height="100">
                        <Rectangle.Fill>
                            <VisualBrush Visual="{Binding Icon, Converter={StaticResource FindResourceFromStringConverter}}" />
                        </Rectangle.Fill>
                    </Rectangle>
                </Grid>
            </DataTemplate>
        </Controls:FlipView.ItemTemplate>
    </Controls:FlipView>
</Grid>
  

MainViewModel.cs

 using Caliburn.Micro;
using Expreriment.Model;
using System;
using System.Collections.ObjectModel;
using System.ComponentModel.Composition;
using System.Linq;

namespace Expreriment.ViewModels
{
    [Export(typeof(MainViewModel))]
    public class MainViewModel : PropertyChangedBase
    {
        //added
        private readonly IWindowManager _windowManager;

        [ImportingConstructor]
        public MainViewModel(IWindowManager windowManager)
        {
            _windowManager = windowManager;
        }

        private void SuggestPresent()
        {
            _windowManager.ShowWindow(new SuggestPresentViewModel(_windowManager));
        }
        //end

        private const string WindowTitleDefault = "Present Presenter";

        private string _windowTitle = WindowTitleDefau<

        public string WindowTitle
        {
            get { return _windowTitle; }
            set
            {
                _windowTitle = value;
                NotifyOfPropertyChange(() => WindowTitle);
            }
        }

        public ObservableCollection<EnumData> _enumData = new ObservableCollection<EnumData>(Enum.GetNames(typeof(CategoryType)).Select(s => new EnumData { Enum = s, IsChecked = false }));
        public ObservableCollection<EnumData> EnumData
        {
            get { return _enumData; }
            set
            {
                _enumData = value;
                NotifyOfPropertyChange(() => EnumData);
            }
        }

        public ObservableCollection<Gift> _gifts = new ObservableCollection<Gift>(GiftAction.GetGifts());

        public ObservableCollection<Gift> Gifts
        {
            get { return _gifts; }
            set
            {
                _gifts = value;
                NotifyOfPropertyChange(() => Gifts);
            }
        }

        public Gift _selectedGift = new Gift();
        public Gift SelectedGift 
        {
            get { return _selectedGift; }
            set
            {
                _selectedGift = value;
                NotifyOfPropertyChange(() => SelectedGift);
            } 
        }
    }
}
  

Я безуспешно пробовал следующие строки:

 "SuggestPresent($orignalsourcecontext)"

cal:Message.Attach="SuggestPresent()" cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}"

cal:Action.TargetWithoutContext="{Binding ElementName=Window, Path=Datacontext}" cal:Message.Attach="SuggestPresent"
  

Ответ №1:

Метод SuggestPresent должен быть public . В настоящее время оно private основано на предоставленном примере. Платформа выполняет поиск общедоступных методов и свойств при привязке к модели представления.

 public void SuggestPresent()
{
    _windowManager.ShowWindow(new SuggestPresentViewModel(_windowManager));
}
  

Комментарии:

1. Я сделал метод общедоступным, но все равно получаю то же исключение.

2. Теперь это работает, я просто удалил cal:Action.TargetWithoutContext часть

3. Вау, спасибо за подсказку с public! Я просто говорю Not seeing the forest for the trees