簡體   English   中英

Xamarin forms 查看型號 Inheritance

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM