[英]Should ViewModels inherit other ViewModels in Xamarin.Forms?
ViewModels
應該繼承其他ViewModels
嗎?
我有一個MerchandiserViewModel
,其中包含Merchandiser
model 的基本屬性和數據庫函數。
MerchandiserViewModel
有一個SelectedMerchandiser
屬性,該屬性保存從ListView
中的ItemSelected
中選擇的Merchandiser
MerchandiserViewModel.cs
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
在App.xaml
中實例化為Static Resource
,因此我只有一個視圖實例 model。
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>
對於與 Merchandiser 相關的每個View
,例如MerchandiserProfile
、 EditProfile
等。我創建一個新的ViewModel
並繼承MerchandiserViewModel
MerchandiserProfileViewModel.cs繼承 MerchandiserViewModel
public class MerchandiserProfileViewModel : MerchandiserViewModel
{
// Logic Specific to the Merchandiser Profile View
}
問題是......當我創建一個新的[Page]ViewModel
並繼承“MerchandiserViewModel”時,我收到以下錯誤消息。
我認為這可能是因為創建了MerchandiserViewModel
的新實例,所以我沒有引用初始SelectedMerchandiser
屬性。
這讓我覺得繼承 ViewModels 不是一個好主意?
這種情況通常如何處理? 我是否應該將每個頁面/視圖的所有邏輯都塞到一個MerchandiserViewModel
中? 我希望我的代碼盡可能干凈和分離,所以如果可能的話想避免這種情況。
經過思考,我是否能夠訪問 C# 中 static 資源中的MerchandiserViewModel
的屬性? 這樣我就可以將所需的屬性傳遞給新的 ViewModel 而無需繼承MerchandiserViewModel
... 想聽聽對此的想法嗎?
MerchandiserViewModel 有一個 SelectedMerchandiser 屬性,該屬性保存從 ListView 中的 ItemSelected 中選擇的 Merchandiser
根據你的描述,你要綁定ListView,對於MerchandiserViewModel,不需要繼承其他ViewModel,建議你看看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>
model class 包含一些綁定到 UI 的屬性。
public class Merchandiser
{
public string Name { get; set; }
public string PhoneNumber { get; set; }
}
MerchandiserViewmodel class,視圖 model 實現視圖可以數據綁定到的屬性和命令,並通過更改通知事件通知視圖任何 state 更改。 視圖 model 提供的屬性和命令定義了 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是class,實現了INotifyPropertyChanged接口,通知數據發生變化。 對於 MerchandiserViewmodel,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();
}
}
更新:
如果您想在 select 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;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.