c# - MultiValueConverter - NotifyPropertyChanged -
have little annoying problem requirements , hope possible solve.
lets assume have following classes:
public class foo { public string name { get; set; } public list<foob> foobs { get; set; } } public class foob { public int id1 { get; set; } public int id2 { get; set; } public decimal sum { get; set; } }
now foo
class has list of foob
givenid1
, id2
values , sum
value gets calculated.
in wpf user interface, have 2 comboboxes
, 1 datagrid
. 1 combobox hold information id1
, other id2
.
now in datagrid, have list of foo
displayed 2 columns 1 name, other gives me headache right now.
the second column should display sum
property of "correct" foob
class.
the correct foob class determined 2 comboboxes in ui , there selecteditem.
what have done far create 2 properties in codebehind: (notice have backingfields , propertychanged specified reduced code main problem)
public int selectedid1 { get; set; } public int selectedid2 { get; set; }
those 2 properties bound corresponding combobox:
<c1:c1combobox itemssource="{binding id1s}" selecteditem="{binding selectedid1}" /> <c1:c1combobox itemssource="{binding id2s}" selecteditem="{binding selectedid2}" />
my datagrid far looks this:
<local:bindingproxy x:key="bindingproxy" data="{binding}" /> <datagrid itemssource={bindings foos}> <datagrid.columns> <datagridtextcolumn binding="{binding name}" /> <datagridtextcolumn> <datagridtextcolumn.binding> <multibinding converter="{staticresource getcorrectfoob}"> <binding binding="."></binding> <binding binding="data.selectedid1"></binding> <binding binding="data.selectedid2"></binding> </multibinding> </datagridtextcolumn.binding> </datagridtextcolumn> </datagrid.columns> </datagrid>
(notice bindingproxy here: http://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/ - enable getting data window within datacontext of datagridrow)
the converter looks this:
public class getcorrectfoob : imultivalueconverter { public object convert(object[] values, type targettype, object parameter, cultureinfo culture) { var foo = (foo)values[0]; var id1 = (int) values[1]; var id2 = (int) values[2]; return foo.foobs.first(x => x.id1 == id1 && x.id2 == id2).sum; } public object[] convertback(object value, type[] targettypes, object parameter, cultureinfo culture) { throw new notimplementedexception(); } }
this works pretty now, behaves correctly when change values in 2 comboboxes in ui , updates information correspondingly but... when underlying sum propertychanges , getting notified propertychanges ui not update.
its working fine if bind column to
<datagridtextcolumn binding="{binding foobs[12].sum}" />
you can imagine dont want have index there, since need update through comboboxes in ui.
hope can me out.
first off, i'm struggling understand how current binding expression presenting sum, converter seems return foob object itself, , not it's sum property - unless you've got specific tostring() implementation on foob class formats present sum, i'm lost.
secondly, think problem stems fact multibinding based off of 2 properties - data.selectedid1 , data.selectedid2, therefore, unless either of 2 properties change, multibinding not going receive propertychanged event , update.
a change of value of sum property of result neither of two, , why view not being updated.
i'm racking brain best way solve this, perhaps should handle in viewmodel, having property named currentfoob or can bind to. set value corresponding foob instance in selectionchanged event handlers of combo box.
your binding like:
<datagrid itemssource={binding foos}> <datagrid.columns> <datagridtextcolumn binding="{binding name}"/> <datagridtextcolumn binding="{binding currentfoob.sum}"/> </datagrid.columns> </datagrid>
now, provided foob implements inotifypropertychanged, view should update when sum of found foob changes.
edit 1 (attempt @ setting source of binding dynamically):
<datagrid itemssource={binding foos}> <datagrid.columns> <datagridtextcolumn binding="{binding name}"/> <datagridtextcolumn> <datagridtextcolumn.binding> <binding path="sum"> <binding.source> <multibinding converter="{staticresource getcorrectfoob}"> <binding binding="."></binding> <binding binding="data.selectedid1"></binding> <binding binding="data.selectedid2"></binding> </multibinding> </binding.source> </binding> </datagridtextcolumn.binding> </datagridtextcolumn> </datagrid.columns> </datagrid>
Comments
Post a Comment