【问题标题】:access and open DisplayActionSheet from view model从视图模型访问并打开 DisplayActionSheet
【发布时间】:2018-08-16 18:18:35
【问题描述】:

我的内容页面中有一个工具栏,其中有一个名为 add 的项目,单击 add 我想打开 DisplayActionSheet

我在 xaml 中创建了 ContentPage Toolbar 并在视图模型中将 ICommand 附加到它。现在 DisplayActionSheet 只能在 View 中访问,因此我不确定如何访问它并从视图模型中渲染它。

xaml 文件

<ContentPage.ToolbarItems>
    <ToolbarItem Name="" Icon="ic_add.png"    Order="Primary" Priority="0" Command="{Binding OnAddContactCommand}"/>
    <ToolbarItem Name="" Icon="ic_search.png" Order="Primary" Priority="1" Command="{Binding OnContactSearchCommand}" />
</ContentPage.ToolbarItems>

查看模型

public ICommand OnContactSearchCommand => new Command(OnContactSearch);
public ICommand OnAddContactCommand => new Command(OnAddContactSearch);

事件

private async void OnAddContactSearch()
{   
   //var action = await DisplayActionSheet(AppResources.select_contact_source, AppResources.cancel, null, AppResources.manual, AppResources.phonebook);
}

private void OnContactSearch()
{
   Debug.WriteLine("OnContactSearch");
}

【问题讨论】:

    标签: xamarin mvvm xamarin.forms


    【解决方案1】:

    就像@Alessandro 所说的Application.Current.MainPage 也适用于操作表和警报。为了从视图模型中隐藏视图特定的东西,我创建了一个IMessageBoxService,它被注入到需要它的视图模型的构造函数中。请注意,我使用的是Autofac IoC container。对于 Xamarin 的 DependencyService,您已更改构造函数并在代码中查找服务。

    IMessageBoxService.cs

    public interface IMessageBoxService
    {
        void ShowAlert(string title, string message, Action onClosed = null);
        // ...
        Task<string> ShowActionSheet(string title, string cancel, string destruction, string[] buttons = null);
    }
    

    MessageBoxService.cs

    public class MessageBoxService : IMessageBoxService
    {
        private static Page CurrentMainPage { get { return Application.Current.MainPage; } }
    
        public async void ShowAlert(string title, string message, Action onClosed = null)
        {
            await CurrentMainPage.DisplayAlert(title, message, TextResources.ButtonOK);
            onClosed?.Invoke();
        }
    
        public async Task<string> ShowActionSheet(string title, string cancel, string destruction = null, string[] buttons = null)
        {
            var displayButtons = buttons ?? new string[] { };
            var action = await CurrentMainPage.DisplayActionSheet(title, cancel, destruction, displayButtons);
            return action;
        }
    }
    

    AppSetup.cs

        protected void RegisterDependencies(ContainerBuilder cb)
        {
            // ...
            cb.RegisterType<MessageBoxService>().As<IMessageBoxService>().SingleInstance();
        }
    

    用法

    public class EditProductViewModel : AddProductViewModel
    {
        private IMessageBoxService _messageBoxService;
    
        public ICommand DeleteCommand { get; set; }
    
        public EditProductViewModel(IPageNavigator navigator, IMessenger messenger,
            IMessageBoxService messageBoxService, TagDataStore tagDataStore) : base(navigator, messenger, tagDataStore)
        {
            _messageBoxService = messageBoxService;
            DeleteCommand = new Command(DeleteItem);
        }
    

    ...

        private async void DeleteItem()
        {
            var action = await _messageBoxService.ShowActionSheet(TextResources.MenuTitleDeleteProduct,
                TextResources.ButtonCancel, TextResources.ButtonDelete);
            if (action == TextResources.ButtonDelete)
            { } // delete
    

    如果您正在执行 viewmodel 首次导航(s.XamarinJonathan Yates' blog),您可以选择将此作为 Navigator 服务的一部分。这是一个品味问题

    【讨论】:

      【解决方案2】:

      试试

      Application.Current.MainPage.DisplayActionSheet();
      

      【讨论】:

      • 这是根据 mvvm 指南访问的正确方法吗?
      • 这项工作,否则我认为你应该使用 MessagingCenter。从 ViewModel 向 View 发送消息,并在 View 中使用 DisplayActionSheet
      • 或者定义一个 ActionSheetDisplayService 并将其注入到你的构造函数中。如果你先做vm导航,你也可以在你的PageNavigatorService中提供接口方法
      • @Kay 你能给我们这个方法的例子吗
      猜你喜欢
      • 2014-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-24
      • 2016-06-25
      • 1970-01-01
      • 2013-02-25
      相关资源
      最近更新 更多