问题描述
应该{{1}}继承其他viewmodels
吗?
我有一个 viewmodels
,其中包含 Merchandiserviewmodel
模型的基本属性和数据库函数。
Merchandiser
具有 Merchandiserviewmodel
属性,该属性将 SelectedMerchandiser
中选定的 Merchandiser
保存在 ItemSelected
ListView
public Merchandiserviewmodel : INotifyPropertyChanged
{
// Property to hold the selected Merchandiser
// Generally I would make this static but then I can't bind the property
public Merchandiser SelectedMerchandiser {get; set;}
// Other logic...
}
在 Merchandiserviewmodel
中被实例化为 Static Resource
,因此我只有一个视图模型实例。
App.xaml
App.xaml
对于与销售商相关的每个 <?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MobileApp.App"
xmlns:viewmodels="clr-namespace:MobileApp.viewmodels">
<Application.Resources>
<viewmodels:Merchandiserviewmodel x:Key="Merchandiserviewmodel" />
<viewmodels:MerchandiserProfileviewmodel x:Key="MerchandiserProfileviewmodel" />
</Application.Resources>
</Application>
,例如View
、MerchandiserProfile
等。我创建了一个新的 EditProfile
并继承了 viewmodel
MerchandiserProfileviewmodel.cs 继承 Merchandiserviewmodel
Merchandiserviewmodel
问题是...当我创建一个新的 public class MerchandiserProfileviewmodel : Merchandiserviewmodel
{
// Logic Specific to the Merchandiser Profile View
}
并继承“Merchandiserviewmodel”时,我收到以下错误消息。
我认为这可能是因为创建了 [Page]viewmodel
的新实例,所以我没有引用初始 Merchandiserviewmodel
属性。
这种情况一般是怎么处理的?我应该将每个页面/视图的所有逻辑都塞进一个 SelectedMerchandiser
中吗?我希望我的代码尽可能干净和分离,因此希望尽可能避免这种情况。
经过深思熟虑
我可以在 C# 中访问静态资源中 Merchandiserviewmodel
的属性吗?这样我就可以在不继承 Merchandiserviewmodel
的情况下将所需的属性传递给新的 viewmodel ... 想听听对此的想法吗?
解决方法
MerchandiserViewModel 有一个 SelectedMerchandiser 属性,该属性保存了 ListView 中 ItemSelected 中选定的 Merchandiser
根据你的描述,你要绑定ListView,MerchandiserViewModel,你不需要继承其他的ViewModel,建议你看看the Model-View-ViewModel Pattern
我做了一个使用 MVVM 绑定 ListView 的示例,请看一下。
<StackLayout>
<ListView
x:Name="listview1"
HasUnevenRows="True"
ItemsSource="{Binding mers}"
SelectedItem="{Binding selecteditem}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label
FontSize="Large"
Text="{Binding Name}"
VerticalOptions="Center" />
<Label
FontSize="Small"
Text="{Binding PhoneNumber}"
VerticalOptions="Center" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
模型类,包含一些绑定到 UI 的属性。
public class Merchandiser
{
public string Name { get; set; }
public string PhoneNumber { get; set; }
}
MerchandiserViewmodel 类,视图模型实现视图可以数据绑定到的属性和命令,并通过更改通知事件通知视图任何状态更改。视图模型提供的属性和命令定义了 UI 提供的功能,但视图决定了该功能的显示方式。
public class MerchandiserViewmodel:ViewModelBase
{
public ObservableCollection<Merchandiser> mers { get; set; }
private Merchandiser _selecteditem;
public Merchandiser selecteditem
{
get { return _selecteditem; }
set
{
_selecteditem = value;
RaisePropertyChanged("selecteditem");
}
}
public MerchandiserViewmodel()
{
mers = new ObservableCollection<Merchandiser>();
getdata();
}
private void getdata()
{
for(int i=0;i<20;i++)
{
Merchandiser mer = new Merchandiser();
mer.Name = "merchandiser "+i;
mer.PhoneNumber = "123";
mers.Add(mer);
}
}
}
ViewModelBase 是实现 INotifyPropertyChanged 接口的类,通知数据发生变化。对于 MerchandiserView 模型,Selected Merchandiser(selecteditem) 必须实现 INotifyPropertyChanged 以在您每次从 ListView 中选择项目时通知数据更改。
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this,new PropertyChangedEventArgs(propertyName));
}
}
}
将 ViewModel 绑定到 ContentPage
public partial class Page10 : ContentPage
{
public Page10()
{
InitializeComponent();
this.BindingContext = new MerchandiserViewmodel();
}
}
更新:
如果您想在选择 ListView 项时导航到详细页面,可以在 ListView_ItemSelected 事件中使用构造函数传递值。
<StackLayout>
<ListView
x:Name="listview1" ItemSelected="listview1_ItemSelected" SelectionMode="Single"
HasUnevenRows="True"
ItemsSource="{Binding mers}"
SelectedItem="{Binding selecteditem}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label
FontSize="Large"
Text="{Binding Name}"
VerticalOptions="Center" />
<Label
FontSize="Small"
Text="{Binding PhoneNumber}"
VerticalOptions="Center" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
private async void listview1_ItemSelected(object sender,SelectedItemChangedEventArgs e)
{
Merchandiser item = (Merchandiser)e.SelectedItem;
await Navigation.PushAsync(new simplecontrol.Page29(item));
}
详细页面:
<ContentPage.Content>
<StackLayout>
<StackLayout Orientation="Horizontal">
<Label Text="Name: " />
<Label
FontSize="Large"
Text="{Binding Name}"
VerticalOptions="Center" />
</StackLayout>
<StackLayout Orientation="Horizontal">
<Label Text="PhoneNumber: " />
<Label
FontSize="Small"
Text="{Binding PhoneNumber}"
VerticalOptions="Center" />
</StackLayout>
</StackLayout>
</ContentPage.Content>
public partial class Page29 : ContentPage
{
public Page29(Merchandiser mer)
{
InitializeComponent();
this.BindingContext = mer;
}
}