Binding a remotable, "observable" collection to a ListView. RRS feed

  • Question

  • I have a client/server application with serveral remote clients and a server that contains a datasource (db). First, let me set up a test case. Forget the db for now and lets say I have a serializeable object Message:

    public class Message : MarshallByRefObject, INotifyPropertyChanged
        private string _text;
        public string Text 
            get { return _text; } 
            set { _text = value; if(ProperyChanged != null) { PropertyChanged(...); } }
        //pretend theres several other properties...
        public event PropertyChangedEventHandler PropertyChanged;

    and a server-side collection of them, RemoteableBindableCollection. I have a remotable object wrapping the collection, something like:

    public class ServerProxy : MarshalByRefObject
        public RemoteableBindableCollection MessageList { get; set; }
        public ServerProxy() 
            MessageList = new...;
            //add here for demonstration 

    In my WPF test page, I have a ListView plus a button and txtbox to add a new msg:

    BUTTON name=AddMessage Click="AddMessage_Click" Add /BUTTON
    TEXTBOX Name="MessageTextBox" /
    LISTVIEW Name="MessageListView"
                GRIDVIEWCOLUMN DisplayMemberBinding="{Binding Text}" Header="Text" /GRIDVIEWCOLUMN
    public partial class TestWindow : Window
        private ServerProxy _server;
        public TestWindow()
            _server = (ServerProxy)Activator.GetObject(typeof(ServerProxy), 
            MessageListView.ItemSource = MessageList;
        private void AddMessage_Click(...)
            _server.MessageList.Add(new Message(MessageTextBox.Text));
        public RemoteablebindableCollection MessageList { get { return _server.MessageList; } }

    Now the goal here is, 2 clients, 1 server running. Client 1 and 2 see the first message in the list. Client 1 adds a new msg via button and both Client's have their ListView's automagically updated.
    Phew, ok. So now the real question. How do you implement RemoteableBindableCollection to enable this?

    It could get large so I'd rather have it derive from MarshallByRefObject so that the [] operator, enumerators etc. return ref's to the contained objects and hopefully only the required data (i.e. the Text property) is serialized to the clients.

    So far the only solution that I have working involves add a function to the page "UpdateMessageList", that resets the binding:

    MessageListView.ItemsSource = MessageList;
    This update function is added to an event in the ServerProxy thats fired when a custom collection calls some "SystemChanged" method in the ServerProxy when the collection changes. 

    I've tried dozens of collection implmentations, for example, a few impls. of serializeable ObservableCollection<T>'s. I get serialization exceptions for anything that derives from MarshallByRefObject and INotifyCollectionChanged. Anyone have any ideas? I'd list all the things I've tried, by my time here has run out for now!





    Friday, April 11, 2008 2:47 PM


All replies

  • Do you have a strong requirement for marshaling your collections by reference? Have you looked through WCF and DataContractSerializer? Why not to pass the raw xml or xaml data across the boundaries?

    Sunday, April 13, 2008 11:43 AM
  • Enabling property/collection change notification across machine boundaries is not merely have your remoteable objects implement INotifyPropertyChanged or INotifyCollectionChanged interface. You have to  provide a mechanism to publish change notification and subscribe change notification across the machine boundaries, here is several approach to this problem:



    Hope this helps
    Monday, April 14, 2008 7:15 AM