【问题标题】:menuflyout choosed item passing to command mvvmmenuflyout 选择的项目传递给命令 mvvm
【发布时间】:2016-07-19 15:55:10
【问题描述】:

我正在尝试将列表视图中所选项目的 menuflyoutitem 绑定到删除命令。 Flyoutmenu 会在我将元素放在列表中时显示,因此我无法将其绑定到 viewmodel 中的 SelectedItem 属性。

SelectedItem 属性工作正常,但我必须先点击元素,然后按住项目以显示菜单,然后删除。如何将发件人从控股传递到我在视图模型中的属性?

查看:

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

提前致谢。

【问题讨论】:

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


    【解决方案1】:

    我今天也遇到了同样的问题,解决方法如下:

    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 是静态的并不是一个糟糕的解决方案,因为你不能同时持有两个项目。

    【讨论】:

      猜你喜欢
      • 2017-06-10
      • 2013-09-30
      • 2017-12-31
      • 1970-01-01
      • 2016-10-30
      • 2015-02-15
      • 2023-03-23
      • 2016-11-05
      • 2018-07-21
      相关资源
      最近更新 更多