menuflyout选择项目传递给命令mvvm

时间:2016-03-31 09:23:50

标签: c# xaml mvvm windows-store-apps prism

我试图将listview中选择项的menuflyoutitem绑定到Delete Command。 Flyoutmenu显示我在列表中持有元素,因此我无法将其绑定到viewmodel中的SelectedItem属性。

SelectedItem属性工作正常,但我必须首先点击元素,然后按住项目显示菜单,然后删除。如何将发件人从Hold传递到viewmodel中的属性?

查看:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <TextBlock Grid.Row="0"
               Text="My List App"
               HorizontalAlignment="Center"
               Style="{ThemeResource HeaderTextBlockStyle}" />
    <ListView x:Name="myListView"
              Grid.Row="1"
              ItemsSource="{Binding AllMyLists}"
              SelectedItem="{Binding SelectedList, Mode=TwoWay}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <i:Interaction.Behaviors>
                        <core:EventTriggerBehavior EventName="Holding">
                            <controls:OpenMenuFlyoutAction />
                        </core:EventTriggerBehavior>
                    </i:Interaction.Behaviors>
                    <FlyoutBase.AttachedFlyout>
                        <MenuFlyout>
                            <MenuFlyoutItem Text="Delete"
                                            Command="{Binding ElementName=myListView, Path=DataContext.DeleteEntryListCommand}" />
                        </MenuFlyout>
                    </FlyoutBase.AttachedFlyout>
                    <TextBlock Text="{Binding Name}"
                               Style="{ThemeResource ListViewItemTextBlockStyle}" />
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>

OpenMenuFlyoutAction用于显示flyoutMenu:

public class OpenMenuFlyoutAction : DependencyObject, IAction
{
    public object Execute(object sender, object parameter)
    {
        FlyoutBase.ShowAttachedFlyout((FrameworkElement)sender);
        return sender;
    }
}

我的ViewModel:

public class AllListsPageViewModel : Microsoft.Practices.Prism.Mvvm.ViewModel, Interfaces.IAllListsPageViewModel
{
    #region Fields

    private ObservableCollection<EntryList> _allMyLists;
    private EntryList _selectedList;

    private DelegateCommand _addEntryListCommand;
    private DelegateCommand _deleteEntryListCommand;

    private readonly INavigationService _navigationService;
    #endregion //Fields

    #region Construction

    public AllListsPageViewModel(INavigationService navigationService) { ... }
    #endregion //Construction

    #region Properties

    public ObservableCollection<EntryList> AllMyLists
    {
        get { return _allMyLists; }
        set { SetProperty(ref _allMyLists, value); }
    }

    public EntryList SelectedList
    {
        get { return _selectedList; }
        set { SetProperty(ref _selectedList, value); }
    }
    #endregion //Properties

    #region Methods

    private void loadData() { }

    private bool _canAddEntryList() { return true; }

    private void _addEntryList() { ... }

    private bool _canDeleteEntryList() { ... }

    private void _deleteEntryList()
    {
        //How to get sender from holding event here?
        _allMyLists.Remove(_selectedList);
    }
    #endregion //Methods

    #region Commands

    public ICommand AddEntryListCommand { ... }

    public ICommand DeleteEntryListCommand
    {
        get
        {
            if (_deleteEntryListCommand == null)
            {
                _deleteEntryListCommand = new DelegateCommand(_deleteEntryList, _canDeleteEntryList);
            }
            return _deleteEntryListCommand;
        }
    }
    #endregion //Commands
}

提前致谢。

1 个答案:

答案 0 :(得分:0)

我今天遇到了同样的问题,我已经解决了如下问题:

namespace your.namespace
{
    using Microsoft.Xaml.Interactivity;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Input;

    public class OpenMenuFlyoutAction : DependencyObject, IAction
    {
        private static object holdedObject;

        public object Execute(object sender, object parameter)
        {
            FrameworkElement senderElement = sender as FrameworkElement;
            FlyoutBase flyoutBase = FlyoutBase.GetAttachedFlyout(senderElement);
            flyoutBase.ShowAt(senderElement);

            var eventArgs = parameter as HoldingRoutedEventArgs;
            if (eventArgs == null)
            {
                return null;
            }

            var element = eventArgs.OriginalSource as FrameworkElement;
            if (element != null)
            {
                HoldedObject = element.DataContext;
            }

            return null;
        }

        public static object HoldedObject
        {
            get { return holdedObject; }
            set
            {
                holdedObject = value;
            }
        }
    }
}

然后您可以按如下方式访问该对象:

var foo = OpenMenuFlyoutAction.HoldedObject as Foo;

我认为HoldedObject是静态的并不是一个好的解决方案,因为你无法同时保存两个项目。