当属性更改-属性更改事件未激发-WinRT/XAML时,在视图中更新复杂对象



我有一个WinRT应用程序,里面有很多用户、项目、会议等。

我有一个主屏幕,主屏幕视图模型应该显示CurrentUser,并且有一个绑定到CurrentUser.ProjectList.的ListView

我使用UserProvider类在ViewModel中初始化CurrentUser,该类从数据库中获取所有必需的信息。

然后,我的问题变得非常类似:订阅嵌套(子)对象的INotifyPropertyChanged

我有一个用户和项目模型:

public class User
{
    public int id { get; set; }
    public string ForeName { get; set; }
    public string Surname { get; set; }
    ... etc ...
    public ObservableCollection<Project> ProjectList { get; set; }
    public ObservableCollection<User> FriendList { get; set; }
     ... constructor
}
public class Project 
{
    public String Name { get; set; }
    public int Id { get; set; }
    public List<User> Users { get; set; }
    public List<Meeting> Meetings { get; set; }
     .. constructor ...
 }

具有以下内容的视图模型:

class HomeScreenViewModel : INotifyPropertyChanged {
private User _currentUser;
public User CurrentUser
 {
    get { return this._currentUser; }
    set
        {
          if (Equals(_currentUser, value)) return;
          this._currentUser = value;
          RaisePropertyChanged("CurrentUser");
        }
  }
    //[field: NonSerialized]
    public event PropertyChangedEventHandler PropertyChanged;
    protected void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

我在这个视图模型中有一个方法,它可以获得当前用户

    public async Task<bool> GetLoggedInUserAsync()
    {
        int testId = 0;
        CurrentUser = await userProvider.GetCurrentUser(testId);
        UserProjects = await userProvider.GetUsersProject(CurrentUser);
        CurrentUser.ProjectList = UserProjects;
        return true;
    }

这在视图的loadState 中被调用

    public MainPage()
    {
        this.InitializeComponent();
        addMeeting = new AddMeetingFlyout();
        _vm = new HomeScreenViewModel();
        this.DataContext = _vm;
    }
    protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
    {
         await _vm.GetLoggedInUserAsync()
    }

我在XAML中的绑定,例如ProjectList和ForeName,如下所示:

        <CollectionViewSource
        x:Name="projectsViewSource"
        Source="{Binding CurrentUser.ProjectList}"/>
   ...
    <ListView
        x:Name="projectList"
        ItemsSource="{Binding Source={StaticResource projectsViewSource}}"
        Grid.Row="1"
        SelectionMode="None"
        Style="{StaticResource DraggableListView}" 
        ScrollViewer.VerticalScrollBarVisibility="Visible"
        IsItemClickEnabled="True" 
    >
        <ListView.ItemTemplate>
            <DataTemplate>
                <Button Style="{StaticResource ProjectTileButton}" Content="{Binding                Name}" Click="ProjectItem_Click"   />
            </DataTemplate>
        </ListView.ItemTemplate>
        <AddDeleteThemeTransition/>
    </ListView>
      ...
         <Button  ...>
            <TextBlock ...">
             <Run Text="{Binding CurrentUser.ForeName}" />
            </TextBlock>
        </Button>

按钮内容CurrentUser.ForeName在视图模型中首次初始化CurrentUser时会触发INotifyPropertyChanged事件。这反映在视图中,但对CurrentUser.ForeName的任何进一步更改都不会引发任何后续的INotifyPropertyChanged事件。ProjectList也不会显示在视图中,并且不会激发INotifyPropertyChanged事件,即使我知道它在那里。

我花了很多天的时间研究实现INotifyPropertyChanged,以便对嵌套的子复杂对象(如CurrentUser.ProjectList)的更改能够传播到视图中。目前,发生这种情况的唯一方法是我强行打电话给

            this._currentUser = value;
            RaisePropertyChanged("CurrentUser");

我正在用一个按钮测试它,该按钮调用视图模型中名为MakeChange()的方法

    public void MakeChange()
    {
        User updatedCurrentUser = CurrentUser;
        CurrentUser = updatedCurrentUser;
    }    

这是有效的,所以我知道所有数据都正确地来自数据库,而且一切都是应该的——少了一件需要担心的事情!

然而,我根本无法获得在页面加载时或添加新项目时显示用户项目的视图。

我尝试实施此解决方案:https://gist.github.com/thojaw/705450然而,WinRT的反射能力已经发生了变化,我不确定如何在我的项目中使用以下留置权,因为这超出了我的能力范围:

     //from property
      //in _type.GetProperties(BindingFlags.Instance | BindingFlags.Public)
      //where _inotifyType.IsAssignableFrom(property.PropertyType)
      //select property;

任何帮助都将不胜感激——我真的以为我所要做的就是将CurrentUser.ProjectList绑定到ListView。

在替换整个ObservableCollection本身时,还需要为集合属性引入另一个属性更改事件和支持字段。

这里有一个很好的例子

相关内容

  • 没有找到相关文章

最新更新