c# - Refresh binding with converter bound to other property -


i building winrt app windows 10 , facing issue can't seem find answer for.

in main page, have list of map markers bound observablecollection in viewmodel. each of these markers, need display text can either property1 or property2 mapmarker class, based on value of property (let's call propertyselector) of viewmodel.

the best solution found make struct contains both property1 , property2 in mapmarker class, bind text field of marker , use converter choose 1 display.

since can't bind property converterparameter, implemented dependencyproperty in converter give access propertyselector. dp works fine, property in converter gets updated, markers never updated. it's because didn't trigger event told marker update, didn't manage achieve adding propertychanged("markerlist") propertyselector setter or trying refresh programmatically bindings when change property things getbinding(text).updatesource(), way seem have different implementation wpf.

am doing right ? can force bindings refresh ?

here relevant code :

mainpage.xaml

<page.resources>         <local:propertyselectorconverter x:key="propertyselectorconverter"                                     propertyselector="{binding propertyselector}" /> </page.resources>  ...  <maps:mapcontrol>     <maps:mapitemscontrol itemssource="{binding markerlist}">         <maps:mapitemscontrol.itemtemplate>             <datatemplate>                 <textblock text="{binding properties, converter={staticresource propertyselectorconverter}}" />             </datatemplate>         </maps:mapitemscontrol.itemtemplate>     </maps:mapitemscontrol> </maps:mapcontrol> <button text="switch data" click="switchbutton_click" /> 

mainpage.xaml.cs

public void switchbutton_click(object sender, eventargs e) {     viewmodel.propertyselector= !viewmodel.propertyselector } 

viewmodel.cs

class viewmodel : inotifypropertychanged {     private observablecollection<marker> markerlist = new observablecollection<marker>();     public observablecollection<marker> markerlist     {         { return markerlist; }         set { markerlist = value; onpropertychanged("markerlist"); }     }      private bool propertyselector = false;     public bool propertyselector     {         { return propertyselector; }         set { propertyselector = value; onpropertychanged("propertyselector"); }     } } 

marker.cs

public class marker {     public tuple<double, double> properties { get; set; } = tuple.create(10, 7); } 

converter.cs

public class propertyselectorconverter : dependencyobject, ivalueconverter {     public bool propertyselector     {         { return (bool)getvalue(propertyselectorproperty); }         set { setvalue(propertyselectorproperty, value); }     }      public static readonly dependencyproperty propertyselectorproperty =         dependencyproperty.register("propertyselector", typeof(bool), typeof(propertyselectorconverter), new propertymetadata(null, currentitemchangedcallback));      private static void currentitemchangedcallback(dependencyobject dependencyobject, dependencypropertychangedeventargs args)     {      }      public object convert(object value, type targettype, object parameter, string language)     {         var properties = (tuple<double, double>)value;         return propertyselector ? properties.item1 : properties.item2;     }      public object convertback(object value, type targettype, object parameter, string language)     {         throw new notimplementedexception();     } } 

thank time.

lacking a good, minimal, complete code example illustrates question, difficult if not impossible provide specific advice. there general thoughts share…

first, in experience converterparameter more useful static (i.e. compile-time) information provided converter. e.g. when have written general-purpose converter needs specific data given binding, data value known @ compile-time.

in scenario, have multiple input values converter vary @ run-time. scenario, imho more appropriate use multibinding. allows provide 2 or more binding sources, wpf recomputed bound value if 1 of sources change. unfortunately, wpf feature and, many useful wpf features, has been omitted windows store/winrt api.

however, can construct simple intermediary view model class accomplish same. example:

class multibindingviewmodel : dependencyobject {     public static readonly dependencyproperty propertiesproperty = dependencyproperty.register(         "properties", typeof(tuple<double, double>), typeof(multibindingviewmodel), new propertymetadata(null, onpropertychanged);     public static readonly dependencyproperty propertyselectorproperty = dependencyproperty.register(         "propertyselector", typeof(bool), typeof(multibindingviewmodel), new propertymetadata(null, onpropertychanged);     public static readonly dependencyproperty valueproperty = dependencyproperty.register(         "value", typeof(double), typeof(multibindingviewmodel), null);      public tuple<double, double> properties     {         { return (tuple<double, double>)getvalue(propertiesproperty); }         set { setvalue(propertiesproperty, value); }     }      public bool propertyselector     {         { return (bool)getvalue(propertyselectorproperty); }         set { setvalue(propertyselectorproperty, value); }     }      public double value     {         { return (double)getvalue(valueproperty); }         set { setvalue(valueproperty, value); }     }      private static void onpropertychanged(dependencyobject d, dependencypropertychangedeventargs e)     {         multibindingviewmodel model = (multibindingviewmodel)d;          model.value = model.propertyselector ? model.properties.item1 : model.properties.item2;     } } 

then use in xaml, like:

<textblock>     <textblock.text>         <binding path="value">             <binding.source>                 <local:multibindingviewmodel properties="{binding properties}"                                              propertyselector="{binding propertyselector}/>             </binding.source>         </binding>     </textblock.text> </textblock> 

caveat: lacking complete code example start with, above browser-written code. there may syntax errors, or might have left out key windows store-required code. sure, exact binding sources, paths, , xml namespace may need tweaking, have no way know sure how you've set data contexts, etc.

but above shows enough basic approach can use in project.


completeness, here wpf approach using multibinding like:

a multibinding always have converter, implementing imultivalueconverter. convert() method of interface looks of ivalueconverter, except instead of object value parameter allowing single input value converted, has object[] values parameter.

based on code provided, expect converter this:

public class propertyselectorconverter : imultivalueconverter {         public object convert(object[] values, type targettype, object parameter, string language)     {         var properties = (tuple<double, double>)values[0];         bool propertyselector = (bool)values[1];          return propertyselector ? properties.item1 : properties.item2;     }      public object convertback(object[] values, type targettype, object parameter, string language)     {         throw new notsupportedexception();     } } 

then in xaml, this:

<textblock>     <textblock.text>         <multibinding converter="{staticresource propertyselectorconverter}">             <binding source="." path="properties"/>             <binding source="." path="propertyselector"/>         </multibinding>     </textblock.text> </textblock> 

Comments

Popular posts from this blog

c# - Validate object ID from GET to POST -

node.js - Custom Model Validator SailsJS -

php - Find a regex to take part of Email -