c# - How to update the view after the model has changed? -


say have logger class, loggerviewmodel class , mainwindow textbox. logger class thread-safe singleton, have instance of in application domain.

public sealed class logger : inotifypropertychanged {     private static readonly logger _instance = new logger();      private static readonly object _synclock = new object();     private static list<logentry> _data = new list<logentry>();      /// <summary>     ///      /// </summary>     private logger() { ; }      /// <summary>     ///      /// </summary>     public static logger instance     {         { return _instance; }     }      /// <summary>     ///      /// </summary>     /// <param name="entry"></param>     public void write(logentry entry)     {         lock (_synclock)         {             _data.add(entry);         }         this.raisenotifypropertychanged("entries");     }      /// <summary>     ///      /// </summary>     /// <param name="component"></param>     /// <param name="message"></param>     public void write(string component, string message)     {         logentry entry = logentry.create(component, message);         write(entry);     }      /// <summary>     ///      /// </summary>     public ilist<logentry> entries     {                 {             lock (_synclock)             {                 return new readonlycollection<logentry>(_data);             }         }     }      /// <summary>     ///      /// </summary>     /// <param name="property"></param>     private void raisenotifypropertychanged(string property)     {         var handler = propertychanged;         if (handler != null)         {             handler(this, new propertychangedeventargs(property));         }     }      /// <summary>     ///      /// </summary>     public event propertychangedeventhandler propertychanged; } 

the logger unique instance updated more thread while application running, update textbox on mainwindow whenever model (that logger singleton class) changes.

how connect model , viewmodel between them? emphasize model changed few application thread, read-only point of view of ui.

i provided loggertext property within loggerviewmodel class, since thought following working mechanism. 1. when model (the logger instance) changes, notifies viewmodel. 2. viewmodel receives notify model , create new string containing messages logger. 3. viewmodel notifies view.

public class loggerviewmodel : inotifypropertychanged {     logger _loggermodel;      /// <summary>     ///      /// </summary>     public loggerviewmodel()     {         _loggermodel = logger.instance;     }      /// <summary>     ///      /// </summary>     public string loggertext     {                 {             string text = "";             list<logentry> entries = new list<logentry>(_loggermodel.entries);             foreach (logentry entry in entries)             {                 text += entry.tostring();                 text += "\n";             }             return text;         }     }      public event propertychangedeventhandler propertychanged;      private void raisepropertychanged(string propertyname)     {         // take copy prevent thread issues         propertychangedeventhandler handler = propertychanged;         if (handler != null)         {             handler(this, new propertychangedeventargs(propertyname));         }     } } 

how viewmodel can intercept notifications sent model?

first of not using singleton. when using singleton pattern making hard on when testing or reusing view controllers. instead inject logger dependency loggerviewmodel class.

aside 1 way solve problem register handler propertychanged event on logger , build text when event fires entries property.

in loggerviewmodel add property handler , update loggertext property needed.

public loggerviewmodel(logger loggermodel /* dependency injection*/) {     _loggermodel = loggermodel;     _loggermodel.propertychanged += this.loggermodel_propertychanged; }  private void loggermodel_propertychanged(object sender, propertychangedeventargs args) {     if (args.propertyname == "entries")     {         stringbuilder text = new stringbuilder();  // use stringbuilder performance         list<logentry> entries = new list<logentry>(_loggermodel.entries);         foreach (logentry entry in entries)         {             text.appendline(entry.tostring());         }         this.loggertext = text.tostring();                 } }  private string _loggertext; public string loggertext {     set     {        _loggertext = value;        raisepropertychanged("loggertext");     }          {         return _loggertext;     } } 

disclaimer: above code written without compiler.


Comments

Popular posts from this blog

javascript - Jquery show_hide, what to add in order to make the page scroll to the bottom of the hidden field once button is clicked -

javascript - Highcharts multi-color line -

javascript - Enter key does not work in search box -