WPF treeview to provide custom data entry views -
new wpf
struggling understand concept of how provide individual data entry forms based on treeview
control.
in simple terms have window split in 2 columns, on left have treeview
static data below
<treeview name="treeview1" verticalalignment="top" selecteditemchanged="treeviewitem_selected" > <treeviewitem header="settings" isexpanded="true" isselected="true"> <treeviewitem header="status" isexpanded="true" > <treeviewitem header="info"/> <treeviewitem header="connection"/> </treeviewitem> <treeviewitem header="settings" isexpanded="true"> <treeviewitem header="options"/> <treeviewitem header="ip"/> </treeviewitem> </treeviewitem> </treeviewitem> </treeview>
i have selected node information available in code behind.
i require have form in right hand colum may consist of many different control, each view individual , shown depending on selection treeview
selecteditemchanged
i think have issues understanding context of templates etc, don't know how work . have thought mainstream model should quite simple, starting think may not case, , should have used c++.
any pointers and/or example code great help.
many time.
but starting think may not case, , should have used c++.
no, not really, problem wpf requires different paradigm , "way of thinking" ui frameworks out there.
that's called mvvm
here's take on described:
<window x:class="miscsamples.treeui" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:miscsamples" title="treeui" height="300" width="300"> <grid> <grid.columndefinitions> <columndefinition width="auto"/> <columndefinition/> </grid.columndefinitions> <treeview itemssource="{binding}" minwidth="200" x:name="treeview"> <treeview.itemtemplate> <hierarchicaldatatemplate itemssource="{binding children}"> <textblock text="{binding displayname}"/> </hierarchicaldatatemplate> </treeview.itemtemplate> </treeview> <contentpresenter grid.column="1" content="{binding selecteditem, elementname=treeview}"> <contentpresenter.resources> <datatemplate datatype="{x:type local:treeviewmodelbase}"> <!-- empty --> </datatemplate> <datatemplate datatype="{x:type local:settingsviewmodel}"> <textblock text="{binding somesetting}"/> </datatemplate> <datatemplate datatype="{x:type local:infoviewmodel}"> <stackpanel> <textbox text="{binding someinfotext}"/> <listbox itemssource="{binding infos}"/> </stackpanel> </datatemplate> </contentpresenter.resources> </contentpresenter> </grid> </window>
code behind (boilerplate, instantiating hierarchy support example):
public partial class treeui : window { public treeui() { initializecomponent(); datacontext = new list<treeviewmodelbase> { new settingsviewmodel() { children = { new treeviewmodelbase() { displayname = "status", children = { new infoviewmodel(), new treeviewmodelbase() {displayname = "connection"} } } } } }; } }
viewmodels:
public class treeviewmodelbase: propertychangedbase { public string displayname { get; set; } private list<treeviewmodelbase> _children; public list<treeviewmodelbase> children { { return _children ?? (_children = new list<treeviewmodelbase>()); } } } public class settingsviewmodel: treeviewmodelbase { public string somesetting { get; set; } public settingsviewmodel() { displayname = "settings"; somesetting = "this setting in settings section"; } } public class infoviewmodel: treeviewmodelbase { public string someinfotext { get; set; } public list<string> infos { get; set; } public infoviewmodel() { displayname = "info"; someinfotext = "welcome info section!"; infos = enumerable.range(1, 100).select(x => "info text " + x.tostring()).tolist(); } }
support class (propertychangedbase)
public class propertychangedbase:inotifypropertychanged { public event propertychangedeventhandler propertychanged; protected virtual void onpropertychanged(string propertyname) { application.current.dispatcher.begininvoke((action) (() => { propertychangedeventhandler handler = propertychanged; if (handler != null) handler(this, new propertychangedeventargs(propertyname)); })); } }
result:
a couple of things note:
- each of these
treeviewmodelbase
-derived classes represents "widget". add relevant properties store actual settings values on each. - these rendered right part of screen using proper
datatemplates
shown in xaml. put each "widget view" in separateusercontrol
in order keep mainwindow.xaml clean. - there's not single event, or single line of code manipulates ui elements in example. it's simple, simple properties ,
inotifypropertychanged
. that's how program in wpf. no needselectedindexchanged
or that. - in order support two-way binding, properties must
onpropertychanged("propertyname");
. - let me know if need further assistance.
Comments
Post a Comment