I'm Hosting a WCF service in a WPF application. The WCF service has an Observablecollection which I'm trying to bind to the listview in WPF but i keep getting nullreference exception since the list is empty at the time of intialisation. It only gets elements added when the client connects to the Service. My XAML is below
<ListView HorizontalAlignment="Left" Height="341" Margin="42,35,0,0" VerticalAlignment="Top" Width="621" x:Name="listView">
<ListView.View>
<GridView>
<GridViewColumn Header=" Time" Width="100" DisplayMemberBinding="{Binding Time}"/>
<GridViewColumn Header="Blade Name" Width="200" DisplayMemberBinding="{Binding Name}"/>
</GridView>
</ListView.View>
</ListView>
The Simplified version of the code behind file is below
using System.ServiceModel.Description;
using SomeNameSpace.WCFService;
namespace SomeNameSpace.WPFHost
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
ServiceHost host;
MyClass SingleTonService;
MyClass srvc;
public MainWindow()
{
try
{
SingleTonService = new MyClass();
host = new ServiceHost(SingleTonService, baseAddresses);
host.Open();
var obj = host.SingletonInstance;
srvc = (SomeNameSpace.WCFService.MyClass)obj;
//WPF Section
*** Getting null reference exception here since the list is emtpy ***
listView.ItemsSource = srvc.__clientList;
//Refresh();
}
catch(NullReferenceException e)
{
}
catch (Exception e)
{
host.Abort();
}
}
The simplified WCFService class is as below
using System.Collections.ObjectModel;
namespace SomeNameSpace.WCFService
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,
ConcurrencyMode = ConcurrencyMode.Multiple,
UseSynchronizationContext = false)]
public class MyClass : IMyClass
{
public ObservableCollection<Client> __clientList = new ObservableCollection<Client>();
public ObservableCollection<Client> clientList
{ get { return __clientList; } }
public ICallback Callback
{
get
{
return OperationContext.Current.GetCallbackChannel<ICallback>();
}
}
public bool Connect(Client client)
{
if (!clients.ContainsValue(CurrentCallback) && !SearchByName(client.Name))
{
__clientList.Add(client);
}
return true;
}
return false;
}
}
Client Class
[DataContract]
public class Client
{
private string _name;
private DateTime _time;
[DataMember]
public string Name
{
get { return _name; }
set { _name = value; }
}
[DataMember]
public DateTime Time
{
get { return _time; }
set { _time = value; }
}
}
Also, If i bind the observablecollection to the listview after the connect method is called, everything works since the list isn't empty but i can't do this at run time since i tested this using buttonclick event and setting listview.itemsource in the event after the connect method is called. There will not be any buttons in the final code.
i replaced the line below
listView.ItemsSource = srvc.__clientList;
with
srvc.__clientList.CollectionChanged += OnCollectionChanged;
and in the event handler i used the code below to manually update the list
this.Dispatcher.Invoke((Action)(() =>
{
listView.Items.Clear();
//update listview here
}));