2017-07-05 9 views
0

J'essaie d'utiliser un MvxDialogFragment pour afficher une boîte de dialogue liée aux données d'une activité. Mon dialogue ViewModel est la suivante:Qu'est-ce qu'un moyen simple d'afficher un MvxDialogFragment?

public class ContainerDialogViewModel : MvxViewModel 
{ 

    public string ShipperName; 

    public void Init(string Name) 
    { 
     ShipperName = Name; 
     LoadData(); 
    } 

    public void LoadData() 
    { 
     Survey = SurveyDataSource.CurrSurvey; 
    } 

    private ShipmentSurvey _Survey; 
    public ShipmentSurvey Survey 
    { 
     get 
     { 
      return _Survey; 
     } 
     set 
     { 
      _Survey = value; 
      RaisePropertyChanged(() => Survey); 
      RaisePropertyChanged(() => Containers); 
     } 
    } 


    public List<ShipmentSurveyContainer> Containers 
    { 
     get 
     { 
      if (Survey == null) 
       return new List<ShipmentSurveyContainer>(); 
      else 
       return Survey.SurveyContainers.ToList(); 
     } 
    } 

} 

Le MvxDialogFragment est codé comme suit:

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

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

     return base.OnCreateDialog(savedState); 
    } 

} 

Dans mon activité, je suis en train de trouver la façon la plus simple de lancer la boîte de dialogue. Voici ce que j'ai essayé:

public class SurveyView : MvxActivity 
{ 
    public void ShowContainerDialog() 
    { 
     ContainerDialogViewModel vm = new ViewModels.ContainerDialogViewModel(); 
     vm.Init("Test Name"); 
     var dialogFragment = new ContainerDialog() 
     { 
      DataContext = vm 
     }; 
     dialogFragment.Show(FragmentManager, "Containers"); 
    } 
} 

Je suis assez sûr que ma méthode de création du modèle de vue est peu orthodoxe, mais je ne sais pas une autre façon de le faire. Le plus gros problème est que FragmentManager est casté à la mauvaise version. Show recherche un Android.Support.V4.App.FragmentManager et le FragmentManager exposé est un Android.App.FragmentManager. J'ai essayé de changer le MvxActivity en MvxFragmentActivity, mais cela n'a pas semblé aider. Quelqu'un peut me diriger dans la bonne direction?

+0

Un nouveau présentateur avec prise en charge des boîtes de dialogue est prévu pour 5.1.0 – Martijn00

+0

@ Martijn00 Existe-t-il un moyen de le faire fonctionner maintenant? Comme avec un présentateur personnalisé ou quelque chose comme ça? J'ai recherché haut et bas pour un exemple de travail d'un MvxDialogFragment et n'ai pas pu trouver un. –

+0

Je travaille sur ce sujet: https://github.com/MvvmCross/MvvmCross/issues/1934 – Martijn00

Répondre

1

MvvmCross ne supporte pas vraiment quand je tentais de le faire, mais je est venu à travers une autre instance où j'avais besoin de cela et hélas, la fonctionnalité est là. Merci à @ Martijn00 pour m'avoir indiqué la solution. Ce sera très basique, mais je pense que cela pourrait aider quelqu'un.

Ma mise en page:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:local="http://schemas.android.com/apk/res-auto" 
    android:orientation="vertical" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"> 
    <TextView 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     style="@style/TableHeaderTextView" 
     android:text="Work Date"/> 
    <MvxDatePicker 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:textSize="20dp" 
    local:MvxBind="Value WorkDate" /> 
    <Button 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:text="Close" 
     local:MvxBind="Click CloseCommand" /> 
</LinearLayout> 

Mon ViewModel:

public class HoursDateDialogViewModel : MvxViewModel<EstimateHours> 
{ 
    private readonly IMvxNavigationService _navigationService; 

    public HoursDateDialogViewModel(IMvxNavigationService navigationService) 
    { 
     _navigationService = navigationService; 

     CloseCommand = new MvxAsyncCommand(async() => await _navigationService.Close(this)); 
    } 

    public override System.Threading.Tasks.Task Initialize() 
    { 
     return base.Initialize(); 
    } 

    public override void Prepare(EstimateHours parm) 
    { 
     base.Prepare(); 
     Hours = parm; 
    } 

    public IMvxAsyncCommand CloseCommand { get; private set; } 

    private EstimateHours _Hours; 
    public EstimateHours Hours 
    { 
     get 
     { 
      return _Hours; 
       } 
     set 
     { 
      _Hours = value; 
      RaisePropertyChanged(() => Hours); 
      RaisePropertyChanged(() => WorkDate); 
     } 
    } 

    public DateTime WorkDate 
    { 
     get 
     { 
      return Hours.StartTime ?? DateTime.Today; 
     } 
     set 
     { 
      DateTime s = Hours.StartTime ?? DateTime.Today; 
      DateTime d = new DateTime(value.Year, value.Month, value.Day, s.Hour, s.Minute, s.Second); 
      Hours.StartTime = d; 
      DateTime e = Hours.EndTime ?? DateTime.Today; 
      d = new DateTime(value.Year, value.Month, value.Day, e.Hour, e.Minute, e.Second); 
      Hours.EndTime = d; 
      RaisePropertyChanged(() => WorkDate); 
     } 
    } 

} 

Mon Vue:

[MvxDialogFragmentPresentation] 
[Register(nameof(HoursDateDialogView))] 
public class HoursDateDialogView : MvxDialogFragment<HoursDateDialogViewModel> 
{ 
    public HoursDateDialogView() 
    { 
    } 

    protected HoursDateDialogView(IntPtr javaReference, JniHandleOwnership transfer) 
     : base(javaReference, transfer) 
    { 
    } 

    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    { 
     var ignore = base.OnCreateView(inflater, container, savedInstanceState); 

     var view = this.BindingInflate(Resource.Layout.HoursDateDialogView, null); 

     return view; 
    } 
} 

C'est tout ce qu'il ya à faire. Je suis capable de passer un objet de paramètre et de lier une partie de l'objet à un MvxDatePicker. Pour afficher cette boîte de dialogue, d'abord dans votre Setup.cs, vous avez besoin:

protected override IMvxAndroidViewPresenter CreateViewPresenter() 
    { 
     return new MvxAppCompatViewPresenter(AndroidViewAssemblies); 
    } 

Dans votre viewmodel à partir de laquelle vous ouvrez la boîte de dialogue, vous avez besoin d'un constructeur contenant:

private readonly IMvxNavigationService _navigationService; 

    public LocalHourlyViewModel(IMvxNavigationService navigationService) 
    { 
     _navigationService = navigationService; 
    } 

Ce injectent le service de navigation pour que vous puissiez travailler avec. Et enfin, tout ce que vous avez à faire pour ouvrir la boîte de dialogue est:

async() => await _navigationService.Navigate<HoursDateDialogViewModel, EstimateHours>(Item); 

Je suis vous avez même pas sûr d'attendre l'appel, mais je suivais l'exemple. Vous pouvez voir plus d'exemples sur le lien @ Martijn00 fourni:

https://github.com/MvvmCross/MvvmCross/tree/develop/TestProjects/Playground

Cheers!

0

J'ai essayé de changer le MvxActivity à un MvxFragmentActivity

Ce fut la première étape correcte. Puis au lieu de passer en FragmentManager, passez en SupportFragmentManager.

Si vous n'êtes pas familier avec le soutien des bibliothèques, vous pouvez lire plus sur ce qu'ils sont et comment les utiliser avec Xamarin here

+0

Vos suggestions l'ont fait compiler correctement et exécuter, mais lorsque la boîte de dialogue a été affichée, elle était vide. Il gonfle la vue donc je ne sais pas quoi faire ensuite. –

+1

@JimWilcox - Au lieu d'utiliser OnCreateDialog, remplacez à la place OnCreateView et gonflez votre mise en page là. Vous pouvez vous débarrasser de OnCreateDialog. Consultez les commentaires dans ce bloc de code pour plus d'informations: https://stackoverflow.com/a/19302991/2754727 – pnavk