如何使用ShowViewModel显示MvxDialogFragment

时间:2016-05-04 16:59:43

标签: c# xamarin xamarin.android mvvmcross

我有一个MvxDialogFragment,我希望使用ViewModel来展示,类似地,当使用ShowViewModel从ViewModel显示一个活动时。可能吗?我怎么能这样做?

这是我的场景:我有一个包含MvxListView的页面,当用户点击listview项目时,我想显示一个MvxDialogFragment。

我的ListView布局:

<Mvx.MvxListView
                    android:id="@+id/lstViewTasks"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:dividerHeight="1px"
                    android:clickable="true"
                    android:focusableInTouchMode="true"
                    android:choiceMode="multipleChoice"
                    android:layout_alignParentTop="true"
                    local:MvxBind="ItemsSource Tasks; ItemClick ItemClickCommand"
                    local:MvxItemTemplate="@layout/projectmytasksitem" />

我的ListView ViewModel:

public class ProjectMyTasksViewModel : MvxViewModel
{
    #region [Atributos privados]

    private ProjectService _service;

    #endregion

    #region [Propriedades]

    private IList<Task> _tasks;
    public IList<Task> Tasks
    {
        get { return _tasks; }
        set { _tasks = value; RaisePropertyChanged(() => Tasks); }
    }

    private bool _isListaVazia;
    public bool IsListaVazia
    {
        get { return _isListaVazia; }
        set { _isListaVazia = value; RaisePropertyChanged(() => IsListaVazia); }
    }

    private Task _selectedTask;
    public Task SelectedTask
    {
        get { return _selectedTask; }
        set { _selectedTask = value; RaisePropertyChanged(() => SelectedTask); }
    }        

    private string _mensagemErro;
    public string MensagemErro
    {
        get { return _mensagemErro; }
        set { _mensagemErro = value; RaisePropertyChanged(() => MensagemErro); }
    }

    #endregion

    #region [Commands]

    private IMvxCommand _itenClickCommand;
    public IMvxCommand ItemClickCommand
    {
        get
        {
            this._itenClickCommand = this._itenClickCommand ?? new MvxCommand<Task>(this.ExecuteItemClickCommand);
            return _itenClickCommand;
        }
    }

    #endregion

    #region [Construtores]

    public ProjectMyTasksViewModel()
    {
        _service = new ProjectService();
        this.CriaListaTeste();
        IsListaVazia = (Tasks.Count > 0) ? true : false;
    }

    #endregion

    #region [Execuções dos Comandos]

    private void ExecuteItemClickCommand(Task task)
    {
        Dictionary<string, Task> parametros = new Dictionary<string, Task>()
        {
            {"Task", task }
        };

        this.ShowViewModel<TaskViewModel>(parametros);
    }

    #endregion

    #region [Métodos]

    public void CriaListaTeste()
    {
        Tasks = new List<Task>();

        for (int indiceProjeto = 1; indiceProjeto <= 10; indiceProjeto++)
        {
            Tasks.Add(new Task { Name = $"Tarefa {indiceProjeto}", StartDate = DateTime.Now, FinishDate = DateTime.Now, IsCompleted = false });
        }
    }

    #endregion        
}

我的Listview活动:

[Activity(Label = "My Task",
    ConfigurationChanges = ConfigChanges.Orientation,
    ScreenOrientation = ScreenOrientation.Portrait)]
public class ProjectMyTasksView : MvxActivity
{
    public new ProjectMyTasksViewModel viewModel
    {
        get { return (ProjectMyTasksViewModel)base.ViewModel; }
        set { base.ViewModel = value; }
    }        

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        this.SetContentView(Resource.Layout.ProjectMyTasksView);
    }
}

我的对话片段:

public class ProjectMyTaskDialog : MvxDialogFragment<TaskViewModel>
{
    public override Dialog OnCreateDialog(Bundle savedState)
    {
        base.EnsureBindingContextSet(savedState);

        this.BindingInflate(Resource.Layout.ProjectMyTasksDialog, null);

        return base.OnCreateDialog(savedState);
    }
}

My Dialog Fragment ViewModel:

public class TaskViewModel : BaseViewModel<TaskService, Task>
{
    #region [Atributos Privados]

    private readonly IMvxPictureChooserTask _pictureChooserTask;

    #endregion

    #region [Commands]

    private MvxCommand _chooseImageCommand;
    public MvxCommand ChooseImageCommand
    {
        get
        {
            _chooseImageCommand = _chooseImageCommand ?? new MvxCommand(ExecuteChooseImageCommand);
            return _chooseImageCommand;
        }
    }

    private MvxCommand _takePictureCommand;
    public MvxCommand TakePictureCommand
    {
        get
        {
            _takePictureCommand = _takePictureCommand ?? new MvxCommand(ExecuteTakePictureCommand);
            return _takePictureCommand;
        }
    }

    private MvxCommand _completeTaskCommand;
    public MvxCommand CompleteTaskCommand
    {
        get
        {
            _completeTaskCommand = _completeTaskCommand ?? new MvxCommand(ExecuteCompleteTaskCommand);
            return _completeTaskCommand;
        }
    }

    #endregion

    #region [Construtores]

    public TaskViewModel(IMvxPictureChooserTask pictureChooserTask)
    {
        _pictureChooserTask = pictureChooserTask;
    }

    #endregion

    #region [Execuções dos Comandos]

    private void ExecuteChooseImageCommand()
    {
        _pictureChooserTask.ChoosePictureFromLibrary(400, 95, OnImage, () => { });
    }

    private void ExecuteTakePictureCommand()
    {
        _pictureChooserTask.TakePicture(400, 95, OnImage, () => { });
    }

    public void ExecuteCompleteTaskCommand()
    {
        throw new NotImplementedException();
    }

    #endregion

    #region [Métodos]

    public void Init(Dictionary<string, Task> parametros)
    {
        Objeto = parametros["Task"];
    }

    private void OnImage(Stream imageStream)
    {
        var memoryStream = new MemoryStream();
        imageStream.CopyTo(memoryStream);

        Objeto.Image = memoryStream.ToArray();
    }
    #endregion

    public class Parametros
    {
        public string TaskJson { get; set; }
    }
}

1 个答案:

答案 0 :(得分:1)

DialogFragments没有演示者。

相反,您可以从Activity中实例化Command,或者对Activity进行回调,该回调确定在调用命令时要执行的操作,即显示对话框。

所以举个简单的例子:

public class MyViewModel : MvxViewModel
{
    public Action ShowTaskCommandAction {get;set;}

    private MvxCommand _showTaskCommand;
    public ICommand ShowTaskCommand =>
        _showTaskCommand = _showTaskCommand ?? (_showTaskCommand = new MvxCommand(DoShowTaskCommand));

    private void DoShowTaskCommand()
    {
        CommandAction?.Invoke();
        // do other stuff here...
    }
}

然后在你的活动或片段中:

public class MyActivity : MvxActivity<MyViewModel>
{
    public void OnCreate(Bundle _)
    {
        base.OnCreate(_);
        ViewModel.ShowTaskCommandAction = () => {
            var dialogFragment = new ProjectMyTaskDialog() {
                DataContext = task
            });
            dialogFragment.Show(FragmentManager);
        };

        // whatever else code
    }
}