c# - WPF custom composite user controls -


first of all, wpf beginner! approach potentially not right way want not hesitate tell me if case. want composite user control in wpf, using mvvm.

some classes better presentation i, here view models:

interface iparameter : inotifypropertychanged {     string name { get; set;}     string value { get; set;} }  class textparameter : viewmodelbase, iparameter  {      private string _value;      public string name { get; private set; }      public string value     {         { return _value; }         set         {             _value = value;             raisepropertychanged();         }     }      public textparameter (string name)     {         this.name = name;     } }  class parameterlist : viewmodelbase, iparameter {     private string _value;      public string name { get; private set; }      public string value     {         { return _value; }         set         {             _value = value;             raisepropertychanged();         }     }        observablecollection<iparameter> parameters { get; set; }      public parameterlist (string name, ienumerable<iparameter> parameters = null)     {         this.name = name;         this.parameters = new observablecollection<iparameter>(parameters ?? new list<iparameter>());     } } 

i using mvvm light, propertychanged stuff managed viewmodelbase. also, not exhaustive list of parameters, there others, more complex issue these ones.

here custom user controls:

textparametercontrol.xaml:

<usercontrol x:class="stuff.textparametercontrol" [..] x:name="parent">     <stackpanel datacontext="{binding elementname=parent}" orientation="horizontal">         <textblock text="{binding path=paramname, stringformat='{}{0}:'}" width="100"></textblock>         <textbox text="{binding path=value}" width="100"></textbox>     </stackpanel> </usercontrol> 

textparametercontrol.xaml.cs :

public class textparametercontrol : usercontrol {     #region param name      public string paramname     {         { return (string)getvalue(paramnameproperty); }         set { setvalue(paramnameproperty, value); }     }      // using dependencyproperty backing store paramname.  enables animation, styling, binding, etc...     public static readonly dependencyproperty paramnameproperty =         dependencyproperty.register("paramname", typeof(string), typeof(textparametercontrol), new propertymetadata(string.empty));      #endregion      #region value      public string value     {         { return (string)getvalue(valueproperty); }         set { setvalue(valueproperty, value); }     }      // using dependencyproperty backing store value.  enables animation, styling, binding, etc...     public static readonly dependencyproperty valueproperty =         dependencyproperty.register("value", typeof(string), typeof(textparametercontrol), new propertymetadata(string.empty));      #endregion      public textparametercontrol()     {         initializecomponent();     } } 

parameterlistcontrol.xaml:

<usercontrol x:class="stuff.parameterlistcontrol" [..] x:name="parent">     <usercontrol.resources>         <datatemplate x:key="textparametertemplate">             <c:textparametercontrol paramname="{binding name}" value="{binding value}"/>         </datatemplate>         <datatemplate x:key="parameterlisttemplate">             <c:parameterlistcontrol paramname="{binding name}" value="{binding value}" items="{binding parameters}" />         </datatemplate>         <s:parametertemplateselector x:key="parameterselector"             textparametertemplate="{staticresource textparametertemplate}"             parameterlisttemplate="{staticresource parameterlisttemplate}"/>     </usercontrol.resources>     <expander datacontext="{binding elementname=parent}" header="{binding path=paramname}" isexpanded="true" expanddirection="down">         <stackpanel>             <itemscontrol itemssource="{binding path=items}" itemtemplateselector="{staticresource parameterselector}"></itemscontrol>         </stackpanel>     </expander> </usercontrol> 

parameterlistcontrol.xaml.cs:

public partial class parameterlistcontrol: usercontrol {     #region param name      public string paramname     {         { return (string)getvalue(paramnameproperty); }         set { setvalue(paramnameproperty, value); }     }      // using dependencyproperty backing store paramname.  enables animation, styling, binding, etc...     public static readonly dependencyproperty paramnameproperty =         dependencyproperty.register("paramname", typeof(string), typeof(parameterlistcontrol), new propertymetadata(string.empty));      #endregion      #region value      public string value     {         { return (string)getvalue(valueproperty); }         set { setvalue(valueproperty, value); }     }      // using dependencyproperty backing store value.  enables animation, styling, binding, etc...     public static readonly dependencyproperty valueproperty =         dependencyproperty.register("value", typeof(string), typeof(parameterlistcontrol), new propertymetadata(string.empty));      #endregion      #region items      public ilist<string> items     {         { return (list<string>)getvalue(itemsproperty); }         set { setvalue(itemsproperty, value); }     }      public static readonly dependencyproperty itemsproperty =         dependencyproperty.register("items", typeof(ilist<string>), typeof(parameterlistcontrol), new propertymetadata(new list<string>()));      #endregion      public parameterlistcontrol()     {         initializecomponent();     } } 

here custom template selector:

class parametertemplateselector : datatemplateselector {     public datatemplate parameterlisttemplate { get; set; }     public datatemplate textparametertemplate { get; set; }      public override datatemplate selecttemplate(object item, dependencyobject container)     {         if (item textparameter)         {             return this.textparametertemplate;         }         else if (item parameterlist)         {             return this.parameterlisttemplate;         }          throw new exception(string.format("this parameter ({0}) not handled in application", item.gettype().name));     } } 

and here calling view , viewmodel:

viewmodel:

public class mainviewmodel : viewmodelbase {     public observablecollection<iparameter> parameters { get; set; }      public mainviewmodel()     {         this.parameters = new observablecollection<iparameter>();         this.parameters.add(new textparameter("customer"));         // here building complex composite parameter list } 

view:

<usercontrol.resources>     <datatemplate x:key="textparametertemplate">         <c:textparametercontrol paramname="{binding name}" value="{binding value}"/>     </datatemplate>     <datatemplate x:key="parameterlisttemplate">         <c:parameterlistcontrol paramname="{binding name}" value="{binding value}" items="{binding parameters}" />     </datatemplate>      <s:parametertemplateselector x:key="parameterselector"         textparametertemplate="{staticresource textparametertemplate}"         parameterlisttemplate="{staticresource parameterlisttemplate}"/> </usercontrol.resources>  <itemscontrol itemssource="{binding parameters}" itemtemplateselector="{staticresource parameterselector}"></itemscontrol> 

when run application, textparameter in mainviewmodel.parameters loaded (vm.name , vm.value properties binded uc.paramname , uc.value. contrariwise, parameterlist in mainviewmodel.parameters partially loaded. uc.name binded uc.paramname vm.parameters not binded uc.items (the uc.datacontext vm, vm.parameters defined, uc.items desperately null).

do have idea of missing ? (i not native speaker, excuse me if english hurts you)

i see have binding mainviewmodel.parameters -> parameterlistcontrol.items might missing binding parameterlistcontrol.items -> parameterlist.parameters. (that's assuming parameterlist viewmodel parameterlistcontrol - provide code datacontext bindings.)

see the accepted answer on question. (ignore comment on caliburn.micro - same solution worked me in mvvm light.)

essentially, in constructor of parameterlistcontrol create binding between dependency property of view , viewmodel's property.

(also, dbl right in comments when debugging binding problems, "unimportant" "plumbing" code omitted important.)


Comments

Popular posts from this blog

asynchronous - C# WinSCP .NET assembly: How to upload multiple files asynchronously -

aws api gateway - SerializationException in posting new Records via Dynamodb Proxy Service in API -

asp.net - Problems sending emails from forum -