我正在尝试使用ShowViewModel<ViewModel, Type>(parameter)
将对象List作为参数传递给同一viewmodel(递归)的不同实例之间的参数。
我在MVVMCross / xamarin表单项目中遇到此错误。
MvvmCross.Platform.Exceptions.MvxException: Failed to construct and
initialize ViewModel for type Project.Core.ViewModels.ObjectViewModel from locator MvxDefaultViewModelLocator - check InnerException for more information ---> MvvmCross.Platform.Exceptions.MvxException: Problem creating viewModel of type ObjectViewModel ---> MvvmCross.Platform.Exceptions.MvxIoCResolveException: Failed to resolve parameter for parameter obj of type ObjectItem when creating Project.Core.ViewModels.ObjectViewModel
at MvvmCross.Platform.IoC.MvxSimpleIoCContainer.GetIoCParameterValues (System.Type type, System.Reflection.ConstructorInfo firstConstructor) [0x00036] in C:\projects\mvvmcross\MvvmCross\Platform\Platform\IoC\MvxSimpleIoCContainer.cs:502
at MvvmCross.Platform.IoC.MvxSimpleIoCContainer.IoCConstruct (System.Type type) [0x0002c] in C:\projects\mvvmcross\MvvmCross\Platform\Platform\IoC\MvxSimpleIoCContainer.cs:312
at MvvmCross.Platform.Mvx.IocConstruct (System.Type t) [0x00006] in C:\projects\mvvmcross\MvvmCross\Platform\Platform\Mvx.cs:169
at MvvmCross.Core.ViewModels.MvxDefaultViewModelLocator.Load (System.Type viewModelType, MvvmCross.Core.ViewModels.IMvxBundle parameterValues, MvvmCross.Core.ViewModels.IMvxBundle savedState) [0x00000] in C:\projects\mvvmcross\MvvmCross\Core\Core\ViewModels\MvxDefaultViewModelLocator.cs:33
解释更多,这是我的代码:
ObjectPage.xaml
<mvx:MvxContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:mvx="clr-namespace:MvvmCross.Forms.Core;assembly=MvvmCross.Forms"
x:Class="Project.Core.Pages.ObjectPage"
Title="Object">
<StackLayout>
<StackLayout>
<StackLayout Padding="5,5,5,5">
<Label Text="{Binding SubTitle}" FontSize="21" VerticalOptions="End"></Label>
</StackLayout>
<StackLayout>
<ListView
ItemsSource="{Binding ObjectItems}"
SelectedItem="{Binding SelectedListItem, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Frame HasShadow="True" Margin="10">
<StackLayout Margin="8">
<Label Text="{Binding Title}"></Label>
</StackLayout>
</Frame>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</StackLayout>
</StackLayout>
ObjectPage.xaml.cs
namespace Project.Core.Pages
{
public partial class ObjectPage
{
public ObjectPage (ObjectItem obj)
{
InitializeComponent ();
BindingContext = new ObjectViewModel(obj);
}
}
}
ObjectViewModel
namespace Project.Core.ViewModels
{
public class ObjectViewModel : ObjectItemViewModel
{
public ObjectViewModel(ObjectItem obj) : base(obj)
{
}
public override void ShowItem()
{
ShowViewModel<ObjectViewModel, ObjectItem>(Obj);
}
}
}
要解释更多:每个Object都有一个ObjectItem列表。每个ObjectItem还有一个ObjectItem列表。 对象继承自ObjectItem。 这是一个例子:
Objects = new List<Object>
{
new Object
{
Title = "Title",
SubTitle="subtitle",
ObjectItems = new List<ObjectItem>
{
new ObjectItem{Title = "title goes here" },
new ObjectItem{Title = "another objectItem title"},
}
}
}
为了加载这些项目,我创建了一个类视图模型,ObjectViewModel从该模型继承了
ObjectItemViewModel.cs
namespace Project.Core.ViewModels
{
public class ObjectItemViewModel : MvxViewModel<ObjectItem>
{
public string Title => (this.Obj == null ? "/!\\ Titre" : this.Obj.Title);
public string SubTitle => (this.Obj == null ? "/!\\ Sous Titre" : this.Obj.SubTitle);
private List<ObjectItemViewModel> _ObjectItems;
public List<ObjectItemViewModel> ObjectItems
{
get => _ObjectItems;
set
{
_ObjectItems = value;
RaisePropertyChanged(() => ObjectItems);
}
}
private ObjectItem _Obj;
public ObjectItem Obj
{
get => _Obj;
set
{
_Obj= value;
RaisePropertyChanged(() => Obj);
}
}
public ObjectItemViewModel _selectedListItem;
public ObjectItemViewModel SelectedListItem
{
get
{
return _selectedListItem;
}
set
{
if (SetProperty(ref _selectedListItem, value))
OnSelectedChangedCommand.Execute(value);
}
}
public ObjectItemViewModel(ObjectItem obj)
{
this.Obj = obj;
loadItems();
}
private MvxCommand<ObjectItemViewModel> _onSelectedChangedCommand;
private ICommand OnSelectedChangedCommand
{
get
{
return _onSelectedChangedCommand ?? (_onSelectedChangedCommand = new MvxCommand<ObjectItemViewModel>((item) =>
{
if (item == null)
{
Debug.WriteLine("Item null");
return;
}
item.ShowItem();
}));
}
}
public virtual void ShowItem()
{
//DO nothing
}
public void loadItems()
{
if (this.Obj != null &&
this.Obj.ObjectItems != null &&
this.Obj.ObjectItems.Count > 0)
{
ObjectItems = new List<ObjectItemViewModel>();
foreach (ObjectItem objectItem in this.Obj.ObjectItems)
{
if (objectItem.MemoItems != null && objectItem.ObjectItems.Count == 1)
{
ObjectItems.Add(new InfoViewModel(objectItem));
}
else
{
ObjectItems.Add(new ObjectViewModel(objectItem));
Debug.WriteLine("Item crée" + objectItem.Title);
}
}
}
}
public override Task Initialize(ObjectItem parameter)
{
Obj = parameter;
return Task.FromResult(0);
}
}
}
答案 0 :(得分:2)
你放在ViewModel的ctor中的所有内容,MvvmCross都将它视为通过依赖注入获得的东西。因此,在您的情况下,由于ObjectItem
未在MvvmCross IoC容器中注册,因此ShowViewModel
无法解析并放入构造函数中。
通常如何解决这个问题,就是使用Init
中的ViewModel
方法来传递对象作为ShowViewModel
调用中的参数。
如果您使用MvvmCross 5.x或更新版本,则在使用新的Initialize
时已移至NavigationService
,但基本要素大致相同。
我认为在你的情况下最快的方法是在你的ObjectViewModel
中添加一个空的构造函数。然后添加Init
方法,在其中分配Obj
道具并调用loadItems()
,类似于非空的ctor。如下所示:
public class ObjectItemViewModel : MvxViewModel<ObjectItem>
{
public ObjectItemViewModel() { }
public void Init(ObjectItem obj)
{
Obj = obj;
loadItems();
}
// rest of code
}
从ObjectItemViewModel
移除ctor,然后将ObjectViewModel
改为:
public class ObjectViewModel : ObjectItemViewModel
{
public override void ShowItem()
{
ShowViewModel<ObjectViewModel, ObjectItem>(Obj);
}
}