/**
* @ManyToMany(targetEntity="Tags")
* @OrderBy({"title" = "ASC"})
*/
private $tags;
函数
NavigateTo<T>()
ItemListViewModel.cs
public static Task NavigateTo<T>()
where T : BaseViewModel
{
// do some very simple navigation/lookups
// basically, just remove the "Model" part of the VM and that is the page
// "converntion-based" :)
var viewModelName = typeof(T).Name;
var pageType = typeof(MainView);
var pageNamespace = pageType.Namespace;
var pageAssembly = pageType.GetTypeInfo().Assembly;
var newPageName = viewModelName.Substring(0, viewModelName.Length - "Model".Length);
var newPageType = pageAssembly.GetType($"{pageNamespace}.{newPageName}");
var newPage = Activator.CreateInstance(newPageType) as Page;
var currentPage = ((NavigationPage)Current.MainPage).CurrentPage;
return currentPage.Navigation.PushAsync(newPage);
}
DataCaptureViewModel.cs
public ItemListViewModel()
{
NextPageCommand = new Command(() => App.NavigateTo<DataCaptureViewModel>());
}
public ObservableCollection<Item> LocalItems
{
get { return localItems; }
set
{
localItems = value;
Refresh(nameof(LocalItems));
}
}
public Command NextPageCommand { get; private set; }
BaseViewModel.cs
public class DataCaptureViewModel : BaseViewModel
{
public DataCaptureViewModel()
{
//will probably have to set passed in param to SelectedItems
//once passing in params gets figured out
}
public ObservableCollection<Item> SelectedItems { get; set; }
}
我一直在使用MVVM模式开发Xamarin.Forms应用程序,并在需要导航到另一个页面时调用using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace Application
{
public abstract class BaseViewModel : INotifyPropertyChanged
{
protected void Refresh([CallerMemberName]string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected bool Set<T>(ref T field, T value, [CallerMemberName]string propertyName = null)
{
if (!object.Equals(field, value))
{
field = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
return true;
}
return false;
}
public event PropertyChangedEventHandler PropertyChanged;
public virtual void OnDisappearing()
{
}
public virtual void OnAppearing()
{
}
}
}
。我现在已经到了一个地步,我想将App.NavigateTo<T>()
传递到我正在浏览的页面中。我无法使用ObservableCollection<Item>
方法弄清楚如何执行此操作。我在NavigateTo<T>()
和WPF
聊天圈中询问过但尚未找到解决方案。有什么想法吗?
如果需要显示更多代码,请告诉我。
答案 0 :(得分:1)
工作原理 :为了传递一些导航参数,您可以使用附加属性存储视图(和视图模型)的状态。我们将绑定模式保持为&#39; OneWayToSource&#39; - 这样一旦绑定 - 它只更新ViewModel,而不是View本身的附加属性;
这样,一旦sudo
方法显式设置附加属性的值,我们就在视图上设置绑定;只要将viewmodel分配给视图NavigateTo
,viewmodel就会因绑定而使用附加值进行更新。
<强> 步骤 强>:
创建附加的可绑定属性。
BindingContext
重构public class NavigationContext
{
public static readonly BindableProperty ParamProperty =
BindableProperty.CreateAttached("Param", typeof(object), typeof(NavigationContext), null,
defaultBindingMode: BindingMode.OneWayToSource);
public static object GetParam(BindableObject view)
{
return view.GetValue(ParamProperty);
}
public static void SetParam(BindableObject view, object value)
{
view.SetValue(ParamProperty, value);
}
// add more properties if more parameters to be passed..
}
以接受参数,并指定属性值。
NavigateTo
确保在(DataCapture)视图XAML中创建对属性的绑定。例如:
public static Task NavigateTo<T>(object param = null)
where T : BaseViewModel
{
// do some very simple navigation/lookups
// basically, just remove the "Model" part of the VM and that is the page
// "converntion-based" :)
var viewModelName = typeof(T).Name;
var pageType = typeof(MainView);
var pageNamespace = pageType.Namespace;
var pageAssembly = pageType.GetTypeInfo().Assembly;
var newPageName = viewModelName.Substring(0, viewModelName.Length - "Model".Length);
var newPageType = pageAssembly.GetType($"{pageNamespace}.{newPageName}");
var newPage = Activator.CreateInstance(newPageType) as Page;
if (param != null)
NavigationContext.SetParam(newPage, param);
var currentPage = ((NavigationPage)App.Current.MainPage).CurrentPage;
return currentPage.Navigation.PushAsync(newPage);
}
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:SampleApp"
x:Class="SampleApp.DataCaptureView"
local:NavigationContext.Param="{Binding SelectedItems}">
<ContentPage.Content>
重构BaseViewModel
以接受参数,并更新视图模型。
NavigateTo
重新使用public static Task NavigateTo<T>(object navigationContext = null)
where T : BaseViewModel
{
// do some very simple navigation/lookups
// basically, just remove the "Model" part of the VM and that is the page
// "converntion-based" :)
var viewModelName = typeof(T).Name;
var pageType = typeof(MainView);
var pageNamespace = pageType.Namespace;
var pageAssembly = pageType.GetTypeInfo().Assembly;
var newPageName = viewModelName.Substring(0, viewModelName.Length - "Model".Length);
var newPageType = pageAssembly.GetType($"{pageNamespace}.{newPageName}");
var newPage = Activator.CreateInstance(newPageType) as Page;
/* newPage.BindingContext ?? */
var viewModel = Activator.CreateInstance<T>();
if (param != null)
viewModel.SetNavigationContext(navigationContext);
newPage.BindingContext = viewModel;
var currentPage = ((NavigationPage)Current.MainPage).CurrentPage;
return currentPage.Navigation.PushAsync(newPage);
}
,或在OnAppearing
SetNavigationContext
之类的方法
BaseViewModel
在public abstract class BaseViewModel : INotifyPropertyChanged
{
.....
public virtual void SetNavigationContext(object context)
{
}
DataCaptureViewModel