c# - Autoscroll ListView in WPF using MVVM -


i try have list automatically scrolls end when adding new line.

here simple mvvm example in want integrate :

there button adds lines list when clicked.

model code :

public class student {     public string lastname {get; set;}     public string firstname {get; set;}      public student(string lastname, string firstname) {         this.lastname = lastname;         this.firstname = firstname;      } }  public class studentsmodel: observablecollection<student> {     private static object _threadlock = new object();     private static studentsmodel current = null;      public static studentsmodel current {         {             lock (_threadlock)             if (current == null)                 current = new studentsmodel();              return current;         }     }      private studentsmodel() {          (int = 1; <= 50; i++)         {             student astudent = new student("student " + i.tostring(), "student " + i.tostring());             add(astudent);         }     }      public void addastudent(string lastname, string firstname) {         student anewstudent = new student(lastname, firstname);         add(anewstudent);     } } 

viewmodel code :

public class mainviewmodel : viewmodelbase {      public studentsmodel students { get; set; }      public mainviewmodel()     {         students = studentsmodel.current;     }      private icommand _addstudent;     public icommand addstudent     {                 {             if (_addstudent == null)             {                 _addstudent = new delegatecommand(delegate()                 {                     students.addastudent("new student lastname", "new student firstname");                 });             }              return _addstudent;         }     } 

view code :

<window x:class="demo.views.mainview" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:c="clr-namespace:demo.commands"> <grid>     <listview  grid.row="2" borderbrush="white" itemssource="{binding path=students}"                horizontalalignment="stretch">         <listview.view>             <gridview>                 <gridviewcolumn header="lastname" displaymemberbinding="{binding path=lastname}" />                 <gridviewcolumn header="firstname" displaymemberbinding="{binding path=firstname}" />              </gridview>         </listview.view>     </listview >     <button content="add" command="{binding addstudent}" margin="601.94,36.866,96.567,419.403" /> </grid> 

thank you

i wrote simple attachedproperty use auto-scroll bottom when bound observablecollection changes:

public class autoscroller : behavior<scrollviewer> {     public object autoscrolltrigger      {         { return (object)getvalue( autoscrolltriggerproperty ); }         set { setvalue( autoscrolltriggerproperty, value ); }     }      public static readonly dependencyproperty autoscrolltriggerproperty =          dependencyproperty.register(               "autoscrolltrigger",              typeof( object ),              typeof( autoscroller ),              new propertymetadata( null, astpropertychanged ) );      private static void astpropertychanged( dependencyobject d, dependencypropertychangedeventargs args )     {         var ts = d autoscroller;                     if( ts == null )             return;          // must attached scrollviewer         var sv = ts.associatedobject scrollviewer;          // check if attached observablecollection, in case         // subscribe collectionchanged scroll when stuff added/removed         var ncol = args.newvalue inotifycollectionchanged;         // new event handler         if( ncol != null )             ncol.collectionchanged += ts.oncollectionchanged;          // remove old eventhandler         var ocol = args.oldvalue inotifycollectionchanged;         if( ocol != null )             ocol.collectionchanged -= ts.oncollectionchanged;           // scroll bottom when bound object changes         if( sv != null && ts.autoscroll )             sv.scrolltobottom();     }      private void oncollectionchanged(object sender, eventargs args)     {         app.current.dispatcher.invoke(delegate {             (this.associatedobject scrollviewer).scrolltobottom();         });     } } 

note: use rx subscribe collectionchanged event, can done normal .net event handling plus dispatcher.invoke .scrolltobottom() call on ui thread.

also note: attached property in behavior class called touchscroller, other stuff too, can simplified simple attached property.

edit:

to use it, in xaml bind property viewmodel:

<scrollviewer ...>     <i:interaction.behaviors>         <util:touchscroller autoscrolltrigger="{binding students}" />     </i:interaction.behaviors>     ... </scrollviewer> 

edit2:

i edited code contain full behavior. use behavior instead of simpley static class attached behavior because gives access .associatedobject, scrollviewer need call .scrolltobottom() on. without using behavior, have keep track of these objects manually. removed rx subscription , added simple event handlers , dispatcher.invoke.

this stripped down , modified version of use, haven't tested version.


Comments

Popular posts from this blog

commonjs - How to write a typescript definition file for a node module that exports a function? -

openid - Okta: Failed to get authorization code through API call -

thorough guide for profiling racket code -