winforms - What is the WPF answer to this? -
i have used wpf develop 2 moderately sized applications. much impressed cleanness of wpf , features. when explained 1 of colleagues (who happens develop business apps) various benefits of wpf, challenged me problem had me totally stumped:
the problem:
he coded application in next way in 2 minutes:
open new winforms project. define classloan
. build project. define object info source using loan
. in info sources explorer, alter view type of loan
info source details. drag info source onto form in designer. supply info source loan[]
containing 1 object. build , run application. the code:
using system; using system.collections.generic; using system.componentmodel; using system.data; using system.drawing; using system.linq; using system.text; using system.windows.forms; namespace winforms_databinding_example { public partial class form1 : form { public form1() { initializecomponent(); } protected override void onload(eventargs e) { base.onload(e); loanbindingsource.datasource = new loan[] { new loan() }; } } public class loan { public decimal amount { get; set; } public decimal rate { get; set; } public decimal total { { homecoming amount * rate; } } } }
the designer:
the application:
now whenever alter value of amount
or rate
in window, value of total
changes accordingly. after explaining useful feature in business apps changes create 1 property in entity updates view calculated properties refreshed instantly making user experience better. considering typical business entity class has lot of properties, saves lot of coding. asked me same in wpf.
i first explained him not understand sort of black magic goes on here. how total
textbox update automatically? first question:
q1. loan
class not implement inotifypropertychanged
or similar. how total
textbox updated when amount
or rate
textboxes lose focus?
then told him not know how same thing in wpf. however, wrote same app in wpf 3 textblock
s , 3 textbox
s in ui. needed create loan
class implement inotifypropertychanged
. added backing fields amount
, rate
. whenever these properties beingness set, raised property changed notification property total
. in end, left app badly aligned controls did same thing winforms app. however, way harder winforms method.
i came home , had bright thought of drag-dropping loan
info source on wpf window (after changed view mode detail). sure enough, got same kind of ui in winforms app , after setting info source same loan[]
in winforms app, seemed complete. ran app, changed amount
, rate
fields hoping see total
alter automagically. however, disappointed. total
field did not change:
the code:
using system; using system.collections.generic; using system.linq; using system.text; using system.windows; using system.windows.controls; using system.windows.data; using system.windows.documents; using system.windows.input; using system.windows.media; using system.windows.media.imaging; using system.windows.navigation; using system.windows.shapes; using winforms_databinding_example; namespace wpf_grid_example { /// <summary> /// interaction logic mainwindow.xaml /// </summary> public partial class mainwindow : window { public mainwindow() { initializecomponent(); } private void window_loaded_1(object sender, routedeventargs e) { system.windows.data.collectionviewsource loanviewsource = ((system.windows.data.collectionviewsource)(this.findresource("loanviewsource"))); // load info setting collectionviewsource.source property: loanviewsource.source = new list<loan>() { new loan() }; } } }
the xaml:
<window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:winforms_databinding_example="clr-namespace:winforms_databinding_example;assembly=winforms_databinding_example" mc:ignorable="d" x:class="wpf_grid_example.mainwindow" title="mainwindow" height="350" width="525" loaded="window_loaded_1"> <window.resources> <collectionviewsource x:key="loanviewsource" d:designsource="{d:designinstance {x:type winforms_databinding_example:loan}, createlist=true}"/> </window.resources> <grid> <grid x:name="grid1" datacontext="{staticresource loanviewsource}" horizontalalignment="left" margin="121,123,0,0" verticalalignment="top"> <grid.columndefinitions> <columndefinition width="auto"/> <columndefinition width="auto"/> </grid.columndefinitions> <grid.rowdefinitions> <rowdefinition height="auto"/> <rowdefinition height="auto"/> <rowdefinition height="auto"/> </grid.rowdefinitions> <label content="amount:" grid.column="0" horizontalalignment="left" margin="3" grid.row="0" verticalalignment="center"/> <textbox x:name="amounttextbox" grid.column="1" horizontalalignment="left" height="23" margin="3" grid.row="0" text="{binding amount, mode=twoway, notifyonvalidationerror=true, validatesonexceptions=true}" verticalalignment="center" width="120"/> <label content="rate:" grid.column="0" horizontalalignment="left" margin="3" grid.row="1" verticalalignment="center"/> <textbox x:name="ratetextbox" grid.column="1" horizontalalignment="left" height="23" margin="3" grid.row="1" text="{binding rate, mode=twoway, notifyonvalidationerror=true, validatesonexceptions=true}" verticalalignment="center" width="120"/> <label content="total:" grid.column="0" horizontalalignment="left" margin="3" grid.row="2" verticalalignment="center"/> <textbox x:name="totaltextbox" grid.column="1" horizontalalignment="left" height="23" margin="3" grid.row="2" text="{binding total, mode=oneway}" verticalalignment="center" width="120"/> </grid> </grid> </window>
q2. confounded before black magic of winforms, confounded because same black magic did not work in wpf. why?
q3. how create wpf version update total
field automatically in winforms example?
q4. platform better/faster sort of business app development? if create improve argument on behalf of wpf, should looking at?
i hope clear problem. please allow me know if clarifications needed. thanks.
q1: if @ designer file windows form you'll see 300 lines of code generated 3 textboxes. of code similar to:
this.amounttextbox.databindings.add( new system.windows.forms.binding("text", this.loanbindingsource, "amount", true));
the binding , bindingsource co-operate update bound values , cause bound controls updated every time 1 of values changes (using reflection).
q2: because wpf designer doesn't create .designer.cs file , associated mess of code. need explicitly implement inotifypropertychange, can simplified using mvvm light's viewmodelbase, e.g.
public class loan : viewmodelbase { public decimal amount { { homecoming this.amount; } set { if (set(() => amount, ref this.amount, value)) { raisepropertychanged(() => total); } } }
q3: 1) when amount or rate changes raise property alter notification property computed property 'total'. 2) modify bindings on amount , rate binding="{binding amount, updatesourcetrigger=lostfocus}"
q4: wpf no question (imho). wpf way more testable , maintainable , understandable.
wpf winforms
No comments:
Post a Comment