である私は、多分私はここで何かをMvvmCrossとXamarinに新しい欠場していますが、私はそれがここで説明しているようView
へViewModel
からいくつかのデータを渡そうとしたときに(ほぼ)MvvmCross - ビューモデルmvxInteractionは常にnull
https://www.mvvmcross.com/documentation/fundamentals/mvxinteraction
しかし、私がそこに通っても、の変数View
の変数は常にnullです!
public IMvxInteraction<MenuViewModel.YesNoQuestion> Interaction
{
get
{
return _interaction;
}
set
{
if (_interaction != null) // <-- Always NULL!
_interaction.Requested -= OnInteractionRequested;
_interaction = value;
_interaction.Requested += OnInteractionRequested;
}
}
のViewModelコード:
public class MenuViewModel : MvxViewModel
{
private IDataScanner _dataScanner { get; set; }
//demo
public class YesNoQuestion
{
public string Question { get; set; }
}
private MvxInteraction<YesNoQuestion> _interaction = new MvxInteraction<YesNoQuestion>();
// need to expose it as a public property for binding (only IMvxInteraction is needed in the view)
public IMvxInteraction<YesNoQuestion> Interaction
{
get
{
return _interaction;
}
}
private void DoFinishProfileCommand()
{
// 1. do cool stuff with profile data
// ...
// 2. request interaction from view
// 3. execution continues in callbacks
var request = new YesNoQuestion
{
Question = "Do you want to save your profile?"
};
_interaction.Raise(request);
}
// demo
public class DataEventArgs : EventArgs
{
public List<string> DataList;
}
public delegate void ScanDoneEvent(object sender, DataEventArgs args);
public event ScanDoneEvent ScanDone;
protected virtual void OnScanDone(List<string> dataList)
{
ScanDone?.Invoke(this, new DataEventArgs { DataList = dataList });
}
public MenuViewModel(IDataScanner dataScanner)
{
_dataScanner = dataScanner;
RunScan();
}
private ObservableCollection<string> _filesCollection;
public ObservableCollection<string> FilesCollection
{
get { return _filesCollection; }
set
{
_filesCollection = value;
RaisePropertyChanged(() => FilesCollection);
}
}
private async void RunScan()
{
var files = await _dataScanner.GetDataListAsync().ConfigureAwait(false);
FilesCollection = new ObservableCollection<string>(files);
DoFinishProfileCommand();
}
}
ビューコード:
[Activity]
public class MenuView : MvxActivity
{
public MenuView()
{
var set = this.CreateBindingSet<MenuView, MenuViewModel>();
set.Bind(this).For(view => view.Interaction).To(viewModel => viewModel.Interaction).OneWay();
set.Apply();
}
protected override void OnViewModelSet()
{
SetContentView(Resource.Layout.menu_view);
}
//demo
private IMvxInteraction<MenuViewModel.YesNoQuestion> _interaction;
public IMvxInteraction<MenuViewModel.YesNoQuestion> Interaction
{
get
{
return _interaction;
}
set
{
if (_interaction != null)// <-- Always NULL!
_interaction.Requested -= OnInteractionRequested;
_interaction = value;
_interaction.Requested += OnInteractionRequested;
}
}
private async void OnInteractionRequested(object sender, MvxValueEventArgs<MenuViewModel.YesNoQuestion> eventArgs)
{
var yesNoQuestion = eventArgs.Value.Question;
// show dialog
Toast.MakeText(this, yesNoQuestion, ToastLength.Long).Show();
}
}
UPD 2017年9月11日
最後に、それは私が望んでいたように動作します。
代わりのnmilcoffとしてMvxInteraction I単に利用されるサービス、(ところで答えのための多くのおかげで)助言、そして私はそれからトーストを呼び出したときにrunOnUiThread
でそれをラップします。
最終的なコードはここにあります。
ToastService:
public class ToastService : IToastService
{
private readonly IMvxAndroidCurrentTopActivity _topActivity;
public ToastService(IMvxAndroidCurrentTopActivity topActivity)
{
_topActivity = topActivity;
}
public void ShowToast(string message)
{
_topActivity.Activity.RunOnUiThread(
() => Toast.MakeText(_topActivity.Activity.ApplicationContext, message, ToastLength.Long).Show()
);
}
}
MenuViewModel:それはMvxInteractionを使用するよう
public class MenuViewModel : MvxViewModel
{
private IDataScanner _dataScanner { get; set; }
private IToastService _toastService { get; set; }
public MenuViewModel(IDataScanner dataScanner, IToastService toastService)
{
_dataScanner = dataScanner;
_toastService = toastService;
}
public override void ViewAppeared()
{
base.ViewAppeared();
RunScan();
}
private ObservableCollection<string> _filesCollection;
public ObservableCollection<string> FilesCollection
{
get { return _filesCollection; }
set
{
_filesCollection = value;
// RaisePropertyChanged(() => FilesCollection);
}
}
private async void RunScan()
{
var files = await _dataScanner.GetDataListAsync().ConfigureAwait(false);
FilesCollection = new ObservableCollection<string>(files);
// Someval = files[0];
_toastService.ShowToast(files[0]);
}
}
ああ、試してみよう! – DanilGholtsman
ああ、今はnullではありませんが、OnIteractionRequestedはトグルされていません。 – DanilGholtsman
OnInteractionRequested内にブレークポイントを設定した場合、ヒットしませんか?それ以外の場合は、デバッガがメソッドにステップインしている場合は、電話のキーボードが表示されていないことを確認します。 – nmilcoff