Caliburn Micro TabItem单击事件没有找到方法的目标

时间:2016-10-20 18:17:36

标签: c# wpf mvvm caliburn.micro mahapps.metro

我正在使用Caliburn Micro从我的View中的MenuItem调用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 = WindowTitleDefault;

        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 个答案:

答案 0 :(得分:2)

方法SuggestPresent必须为public。根据提供的示例,它目前是private。框架在绑定到视图模型时搜索公共方法和属性。

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