WPF绑定到XAML声明的类实例中的Observable Collection

时间:2016-02-14 19:29:47

标签: c# wpf xaml listview

我的 App.xaml 中定义了一个类的实例,因此可以从应用程序的任何位置访问此实例。

班级

using Common;
using System.Collections.ObjectModel;
using System.Windows;

namespace PhotoManagement
{
    public class LoggedUsers : NotifyUIBase
    {
        public ObservableCollection<Logged> Logged = new ObservableCollection<Logged>();
        public void Add(Logged user)
        {
            Logged.Add(user);
            UpdateView(); //Check the List for users
            RaisePropertyChanged("Logged"); //Notify View binding there is a change
        }

        //Check if there is a user logged in
        public void UpdateView()
        {
            if (Logged.Count < 1)
            {
                MessageBox.Show("No one logged in!");
                //No user is logged in, navigate to login view
                //views[0].NavigateExecute(); Does not work, as views object is out of scope
            }
            else
            {
                MessageBox.Show("Someone is logged in!");
                //User is logged in, navigate to home view
            }
        }
    }
}

如下所示,我在XAML中设置了一个类的实例,并给出了一个Key:

<Application x:Class="PhotoManagement.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:PhotoManagement"
             StartupUri="/Views/Main/MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <local:LoggedUsers x:Key="LoggedUsers" />
        </ResourceDictionary>
    </Application.Resources>
</Application>

我已经检查过项目是否已添加到列表中,就像调用 Add()方法时一样,它还会运行 UpdateView()方法有价值。

但是我很难在ListView中显示Items,或者ListView没有得到更新的通知,但它应该是!

<ListView ItemsSource="{Binding Logged, Source={StaticResource LoggedUsers}}" Width="100" Height="100">
    <ListViewItem>
        <TextBlock Text="{Binding FirstName}" />
    </ListViewItem>
</ListView>

即使我向ListView添加项目,上面的ListView仍然是空的。

这也是 Logged 类:

namespace PhotoManagement
{
    public class Logged
    {
        public string ClearPassword { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public long UID { get; set; }
        public string Email { get; set; }

        //Display basic statistics 
        public int ThisDayImageCount { get; set; }
        public int ThisDaySaleCount { get; set; }

        public Logged()
        {
            //Update the stats when instigated
            UpdateStats();
        }

        //Update the stats
        public void UpdateStats()
        {

        }
    }
}

2 个答案:

答案 0 :(得分:1)

代码存在多个问题。

  • Logged应该是属性,而不是字段。你不能绑定到字段。

    public ObservableCollection<Logged> Logged { get; set; }
    

    还要向LoggedUsers添加构造函数以初始化属性(或使用C#6的自动属性初始值设定项):

    public LoggedUsers()
    {
        Logged = new ObservableCollection<Logged>();
    }
    
  • XAML应如下所示:

    <ListView ItemsSource="{Binding Logged, Source={StaticResource LoggedUsers}}" Width="100" Height="100">
        <ListView.ItemTemplate>
            <DataTemplate DataType="local:Logged">
                <TextBlock Text="{Binding FirstName}" />
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
    
  • 我认为你不需要RaisePropertyChanged("Logged");ObservableCollection通知其内容的更改。

完成这些修改后,现在如果你在应用程序的某个地方执行此操作:

var loggedUsers = FindResource("LoggedUsers") as LoggedUsers;

if (loggedUsers != null)
{
    loggedUsers.Add(new Logged()
    {
        FirstName = "John"
    });
}

您将获得更新。

result

答案 1 :(得分:1)

少数事情:

1.您不需要为ObservableCollection<Logged> Logged

调用RaisePropertyChanged
    public void Add(Logged user)
    {
        Logged.Add(user);
        UpdateView(); //Check the List for users
        //You dont need this RaisedPropertyChanged
        RaisePropertyChanged("Logged"); //Notify View binding there is a change
    }

2.Logged应该是一个属性 - ObservableCollection<Logged> Logged {get; private set;}然后使用它的构造函数来初始化它

public LoggedUsers
{
 Logged = new ObservableCollection<Logged>();
}

3.为public class Logged实现INotifyPropertyChanged接口,您将需要它,如果您要更新其构造函数之外的值。

public string ClearPassword { get; set; }

应该是

private string _clearPassword
publuc string ClearPassword
{
  get { return _clearPassword;}
  set
 { 
   _clearPassword = value;
    RaisePropertyChanged("ClearPassword");
  }
}

也为其余属性做这件事。