【问题标题】:MVVM INotifyPropertyChanged not workingMVVM INotifyPropertyChanged 不起作用
【发布时间】:2018-03-19 18:24:04
【问题描述】:

请协助: 我已经使用 Xamarin 在一个简单的应用程序上实现了 MVVM 设计。 我有一个模型(用户)和一个视图模型(用户视图模型)。 请注意,此应用是我的第一个 Xamarin/MVVM 应用,而且我是新手。

我遇到的问题是添加或删除用户,视图不会更新。 当我添加或删除用户时,我可以确认数据库已更新,但不是我的视图。

请看我下面的代码,我错过了什么?

用户模型:

public class User
{
    public int Id { get; set; }
    public string Username { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public bool IsActive { get; set; }

    public List<Role> RolesList { get; set; }
}

UserViewModel 代码:

public class UsersViewModel : INotifyPropertyChanged
        {
        private UserServices UserServ { get; set; }

        public User UserSelected { get; set; }

        private ObservableCollection<User> userList;
        public ObservableCollection<User> UserList
        {
            get
            {
                return userList;
            }
            set
            {
                if (userList != value)
                {
                    userList = value;
                    NotifyPropertyChanged();
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public UsersViewModel()
        {
            UserServ = new UserServices();
            UsersLoadAsync();
        }

        public async void UsersLoadAsync()
        {
            UserList = await UserServ.UsersGetAsync();
        }
    }

用户助手服务代码(为完整性而添加)

public class UserServices
    {

        public async Task<ObservableCollection<User>> UsersGetAsync()
        {
            ObservableCollection<User> UserList = await App.UserService.GetAsync();

            return UserList;
        }

        public async Task<bool> UsersAddAsync(User user)
        {
            bool success = await App.UserService.PostAsync(user);
            return success;
        }

        public async Task<bool> UsersRemoveAsync(User user)
        {
            bool success = await App.UserService.DeleteAsync(user.Id, user);
            return success;
        }

    }

查看 Xaml 代码:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:PB_Logbook"
             x:Class="PB_Logbook.MainPage"
             xmlns:ViewModels="clr-namespace:PB_Logbook.ViewModels;assembly:PB_Logbook">

    <ContentPage.BindingContext>
        <ViewModels:UsersViewModel/>
    </ContentPage.BindingContext>
    <StackLayout>
        <ListView ItemsSource="{Binding UserList, Mode=TwoWay}" HasUnevenRows="True" ItemSelected="Item_SelectedAsync" IsPullToRefreshEnabled="True">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <StackLayout Orientation="Vertical" Padding="12,6">
                        <Label Text="{Binding Username}" FontSize="24"/>
                        <Label Text="{Binding FirstName}" FontSize="18" Opacity="0.6"/>
                        <Label Text="{Binding LastName}" FontSize="18" Opacity="0.6"/>
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
    <Button Text="Add" Clicked="AddButton_ClickedAsync"></Button>
        <Button Text="Remove" Clicked="RemoveButton_ClickedAsync"></Button>
    </StackLayout>


</ContentPage>

查看后面的代码:

public partial class MainPage : ContentPage
    {
        private UserServices UserServices { get; set; }
        private UsersViewModel UsersVM { get; set; }


        public MainPage()
        {
            InitializeComponent();
            UserServices = new UserServices();
            UsersVM = new UsersViewModel();
        }

        private async void AddButton_ClickedAsync(object sender, EventArgs e)
        {
            await AddUserAsync();
        }

        private async void RemoveButton_ClickedAsync(object sender, EventArgs e)
        {
            await RemoveUserAsync();
        }

        private async void Item_SelectedAsync(object sender, EventArgs e)
        {
            UsersVM.UserSelected = ((User)((ListView)sender).SelectedItem);

        }

        private async void Pull_RefreshAsync(object sender, EventArgs e)
        {
            //UsersVM.UsersLoadAsync();
        }

        private async Task AddUserAsync()
        {
            Random rnd = new Random();
            int rndNumber = rnd.Next(1, 100);

            User user = new User()
            {
                Username = "User  " + rndNumber,
                FirstName = "Firstname  " + rndNumber,
                LastName = "Surname " + rndNumber,
                IsActive = true
            };

            bool success = await UserServices.UsersAddAsync(user);

            if (success)
            {
                if (!UsersVM.UserList.Contains(user))
                    UsersVM.UserList.Add(user);
            }
        }

        private async Task RemoveUserAsync()
        {
            bool success = await UserServices.UsersRemoveAsync(UsersVM.UserSelected);

            if (success)
            {
                if (UsersVM.UserList.Contains(UsersVM.UserSelected))
                    UsersVM.UserList.Remove(UsersVM.UserSelected);
            }
        }
    }

问题在于添加/删除在我看来不会更新的用户。

谢谢。

【问题讨论】:

  • ObservableCollection&lt;&gt;替换List&lt;&gt;和你的INotifyPropertyChanged实现。
  • 感谢@jstreet 的回复。我确实用 ObservableCollection 替换了 List 但仍然不起作用。还有其他建议吗?
  • 一有机会我会仔细看看。
  • 什么是App.UserService?您需要发布MCVE
  • 所以,你有 UserServicesApp.UserService 显然两个都没有真正更新 UsersViewModel

标签: xaml xamarin mvvm inotifypropertychanged


【解决方案1】:

如果您是 Xamarin MVVM 的新手,此链接将帮助您了解 Xamarin Forms 中 MVVM 的基础知识

https://deanilvincent.github.io/2017/06/03/basic-understanding-of-mvvm-and-databinding-in-xamarin-forms/

我也建议,请减少你的代码背后的代码,只实现包括 ViewModel 中的命令在内的所有内容。

您已经写到您的代码在保存和更新时可以正常工作,但不能反映视图,对吗?您应该在保存命令之后立即将您的方法放在获取列表中。

像这样在你的 xaml 中

<Button Text="Save" Command="{Binding SaveCommand}"/>

在您的 ViewModel 中,您应该使用 Xamarin 中的命令

public Command SaveCommand{
   get{
      return new Command(async()=>{
           // your command save here
           // then put your method for fetching the updated list: your UsersLoadAsync();
      });
   }
}

如果您是 MVVM 新手,也可以查看此link。它使用 Xamarin MVVM。完成后,您将拥有带有简单 mvvm 实现的简单天气应用程序

希望对你有帮助

【讨论】:

  • 感谢您的帖子。我确实听从了您的建议,并将所有逻辑和命令移至 ViewModel。我也尝试在保存后再次重新加载 List,但它仍然没有刷新视图。
猜你喜欢
  • 2016-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-26
  • 2011-11-26
  • 1970-01-01
  • 2011-06-25
相关资源
最近更新 更多