c# - How to make TwoWay Binding work -


i have problem when put binding mode twoway datagrid won't show. when leave binding mode on default, datagrid apear strings, , cannot find problem. in xaml have 3 more buttons: load(that loads table), update , cancel(that cancel changes , reloads datagrid directly observablecollection.

here xaml datagrid line

<datagrid x:name="datagrid" autogeneratecolumns="true" canvas.left="10" canvas.top="10" alternatingrowbackground="lightgreen" height="245" width="500" itemssource="{binding userss.getvalues, mode=twoway, updatesourcetrigger=propertychanged}" datacontext="{binding relativesource={relativesource self}}"/> 

i have userss class creat observablecollection store data sqlite database.

public class userss : inotifypropertychanged {     public static sqliteconnection m_dd = new sqliteconnection("data source=mydatabase.sqlite;version=3;");      public static observablecollection<userss> usercol = new observablecollection<userss>();     public int id { get; set; }     private string _name;     public string name     {         { return _name; }         set         {             _name = value;             raisepropertychanged();         }     }      private sex _sex;     public sex sex     {         { return _sex; }         set         {             _sex = value;             raisepropertychanged();         }     }      private stations _station;     public stations station     {         { return _station; }         set         {             _station = value;             raisepropertychanged();         }     }      private jobs _job;     public jobs job     {         { return _job; }         set         {             _job = value;             raisepropertychanged();         }     }      private datetime _date;     public datetime date     {         { return _date; }         set         {             _date = value;             raisepropertychanged();         }     }      public static observablecollection<userss> getvalues()     {         m_dd.open();         string sql = "select * user";         usercol.clear();         sqlitecommand cmd = new sqlitecommand(sql, m_dd);         sqlitedatareader reader = cmd.executereader();         while (reader.read())         {             string sex1 = reader["sex"].tostring();             string station1 = reader["station"].tostring();             string job1 = reader["job"].tostring();             string data1 = reader["date"].tostring();             usercol.add(new userss()             {                 id = convert.toint32(reader["id"]),                 name = reader["name"].tostring(),                 sex = (sex)enum.parse(typeof(sex), sex1),                 station = (stations)enum.parse(typeof(stations), station1),                 job = (jobs)enum.parse(typeof(jobs), job1),                 date = convert.todatetime(data1)             });         }         m_dd.close();         return usercol;      }      public event propertychangedeventhandler propertychanged;      private void raisepropertychanged([callermembername] string caller = "")     {         if (propertychanged != null)         {             propertychanged(this, new propertychangedeventargs(caller));         }     } }  public enum sex {     male,     female } public enum jobs {     programmer,     designer,     manager,     cto,     ceo, } public enum stations {     desktop,     laptop,     tablet } 

}

and here implementation mainwindow

public partial class mainwindow : window {     public sqliteconnection m_db = new sqliteconnection("data source=mydatabase.sqlite;version=3;");     sqlitedataadapter adap;     dataset ds;     datatable dt;     sqlitecommandbuilder cmdbl;     string query;     public mainwindow()     {         initializecomponent();     }     private void loadbutton_click(object sender, routedeventargs e)     {         try         {             m_db.open();             observablecollection<userss> cuser = userss.getvalues();             query = "select * user";             adap = new sqlitedataadapter(query, m_db);             ds = new dataset();             adap.fill(ds, "users");             dt = ds.tables[0];             datagrid.datacontext = ds.tables[0].defaultview;             datagrid.itemssource = dt.defaultview;             m_db.close();         }         catch (exception ex)         {             messagebox.show(ex.tostring());         }     }      private void update_click(object sender, routedeventargs e)     {         if (messagebox.show("are sure want make changes?", "please confirm", messageboxbutton.yesno) == messageboxresult.yes)         {             try             {                 cmdbl = new sqlitecommandbuilder(adap);                 adap.update(ds, "users");                 ds.tables[0].acceptchanges();                 datagrid.items.refresh();             }             catch (exception ex)             {                 messagebox.show(ex.message);             }         }         else             this.datagrid.canceledit();     }      private void cancelclick(object sender, routedeventargs e)     {         if (messagebox.show("are sure want cancel changes?", "please confirm", messageboxbutton.yesno) == messageboxresult.yes)         {             datagrid.itemssource = userss.getvalues();         }         else             this.datagrid.canceledit();     } } 

}

btw work in wpf.

hope can me. thanks.

the problem binding function, doesn't work. should bind public property contains list of models want show in datagrid. way need move getvalues call somewhere else, allready have code in loadbutton_click event-handler, reuse that.

so first change change usercol-collection public property instead of public field, because bindings work on public properties, besides want raise propertychangedevent if reference observablecollection changes.

// old code public static observablecollection<userss> usercol = new observablecollection<userss>();  // new code private static observablecollection<userss> usercol = new observablecollection<userss>();  public static observablecollection<userss> usercol {    { return usercol; }    set { usercol = value; raisepropertychanged(); } } 

your getvalues-method doesn't need return type anymore, change void. inside, change every call usercol new public property usercol if changes list happen, gui needs (via raisepropertychanged e.g.)

inside of loadbutton_click doing same in getvalues function doesn't make sense, because don't use userss models anymore. can instead use getvalues-method here reload data (also need event e.g. datagridloaded or fill data @ startup):

private void loadbutton_click(object sender, routedeventargs e) {     // ... exception handling     userss.getvalues(); } 

now bind collection in xaml view:

<datagrid x:name="datagrid" autogeneratecolumns="true" canvas.left="10" canvas.top="10" alternatingrowbackground="lightgreen" height="245" width="500" itemssource="{binding userss.usercol, mode=twoway, updatesourcetrigger=propertychanged}" datacontext="{binding relativesource={relativesource self}}"/> 

note general idea , have not testet code, maybe need fix in view places. think if bit mvvm design pattern structure code in nice fashion.


Comments

Popular posts from this blog

account - Script error login visual studio DefaultLogin_PCore.js -

xcode - CocoaPod Storyboard error: -