[英]Xamarin forms ViewModels Inheritance
我正在為我的寵物項目使用 MVVM 開發有關視頻游戲的 Xamarin forms 應用程序。 我是 Xamarin forms 的新手,我需要你的建議。
我有幾個 ViewModel,里面有相同的代碼。 我決定創建一個基本 ViewModel 並從中繼承其他的。
我有帶有 PropertyChanged 事件的 ViewModelBase:
public class ViewModelBase : INotifyPropertyChanged
{
private string _title;
public string Title
{
get => _title;
set => Set(ref _title, value);
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void Set<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
field = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
我還有一個基本的 GamesViewModel,其他人從中繼承,有很多代碼,這就是為什么我只顯示我正確繼承了所有內容:
public class GamesViewModel : ViewModelBase
以下是派生的 ViewModel:
public class NewGamesViewModel : GamesViewModel
和
public class SearchViewModel : GamesViewModel
問題是我在基本 GamesViewModel 中有 SearchGame 屬性:
private string _searchGame;
public string SearchGame
{
get => _searchGame;
set => Set(ref _searchGame, value);
}
當程序運行時,我將值放在 SearchGame 屬性中,在 GamesViewModel 中我可以看到分配的值,但在派生的 ViewModels 中,值是 null:
例如,在從 GamesViewModel 繼承的 SearchViewModel 中進行調試時,我檢查了該值,它是 null。
var test = SearchGame; - value is null here
我沒有在項目中創建 GamesViewModel 的任何 object。
在 BindingContext 的代碼隱藏文件頁面中,我這樣做:
public partial class SearchGamePage : ContentPage
{
public SearchGamePage()
{
InitializeComponent();
BindingContext = new SearchViewModel();
}
}
我試圖盡可能多地解釋。 也許在 Xamarin forms inheritance 與 ViewModels 工作不明顯。
提前感謝您的幫助!
祝你今天過得愉快!
首先,我制作了一個類似於以下代碼的ViewModelBase
。
public class ViewModelBase : INotifyPropertyChanged
{
private string _title;
public string Title
{
get => _title;
set => SetProperty(ref _title, value);
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs((propertyName)));
}
protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(storage, value))
{
return false;
}
storage = value;
OnPropertyChanged(propertyName);
return true;
}
}
}
我在SearchViewModel
中為SearchGame
設置了一個文本。
public class SearchViewModel : GamesViewModel
{
public SearchViewModel()
{
SearchGame = "test";
}
}
這是有關GamesViewModel
的代碼。
public class GamesViewModel:ViewModelBase
{
private string _searchGame;
public string SearchGame
{
get => _searchGame;
set => SetProperty(ref _searchGame, value);
}
}
然后我制作了一個Label
來綁定SearchGame
屬性,如 xaml。
<Label Text="{Binding SearchGame}"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
這是布局背景代碼。
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
this.BindingContext = new SearchViewModel();
}
}
這是運行截圖。
我向 GamesViewModel 發送了一條消息,其中包含如下搜索游戲值:
MessagingCenter.Send(this, "search_game", titleViewModel.SearchGame);
var detailPage = (Application.Current.MainPage as MasterDetailPage)?.Detail;
await detailPage.Navigation?.PushAsync(new SearchGamePage());
我在 GamesViewModel 構造函數中訂閱此消息並分配給 SearchGame 屬性消息值,如下所示:
MessagingCenter.Subscribe<CustomTitleView, string>(this, "search_game", (sender, message) =>
{
SearchGame = message;
});
但正如您在上面的代碼中看到的那樣,我創建了 SearchGamePage 實例。 SearchGamePage 構造函數調用並在其中創建新的 SearchViewModel 實例:
public partial class SearchGamePage : ContentPage
{
public SearchGamePage()
{
InitializeComponent();
BindingContext = new SearchViewModel();
}
}
這就是為什么 GamesViewModel 構造函數再次調用並在 SearchGame 屬性中分配 null 的原因。
我在 App.xaml.cs 文件中使用 DependencyService.Register 解決了這個問題:
public App()
{
InitializeComponent();
DependencyService.Register<MockDataStore>();
DependencyService.Register<IGameApiClient, GameApiClient>();
DependencyService.Register<IFavoriteGameService, FavoriteGameService>();
DependencyService.Register<GamesViewModel>();
DependencyService.Register<SearchViewModel>();
DependencyService.Register<NewGamesViewModel>();
DependencyService.Register<TitleViewModel>();
MainPage = new MainPage();
}
最后,在 SearchGamePage 構造函數中,我分配給 BindingContext SearchViewModel,如下所示:
public SearchGamePage()
{
InitializeComponent();
BindingContext = DependencyService.Get<SearchViewModel>();
}
現在,當我使用 messenger 為 GamesViewModel 中的 SearchGame 屬性分配值時,一切都很好,我可以在 SearchViewModel 的 SearchGame 屬性中看到相同的值,因為沒有重新創建此 ViewModel。
我知道我在提問時沒有提供完整的信息。 但我希望如果其他人會面臨同樣的問題,這個答案會很有用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.