c# - How to bind a DependencyProperty of a UserControl to a property in it's ViewModel in MVVM? -
the question not how stuff working, does; it's strange behavior i'm experiencing, , need understand it. have resourcedictionary contains styles, 1 of them got targettype="{x:type usercontrol}" , x:key="ucstyle"; 1 applied on multiple usercontrols in project. of these usercontrols got string state property in viewmodel used apply visual states (through external class, , attached property, bound viewmodel in xaml). till point perfect, then, tried add dependencyproperty state usercontrol, , bind state property in viewmodel, attempt was:
<usercontrol.resources> <resourcedictionary> <resourcedictionary.mergeddictionaries> <!--resourcedictionary source="..."/--> </resourcedictionary.mergeddictionaries> <style x:key="mystyle" targettype="{x:type local:myusercontrol}" basedon="{staticresource ucstyle}"> <setter property="state" value="{binding state, mode=twoway}"/> </style> </resourcedictionary> </usercontrol.resources> <usercontrol.style> <dynamicresourceextension resourcekey="mystyle" /> </usercontrol.style> this worked @ runtime, in design-time, underline these lines 
and shows error says:
'myusercontrol' targettype doesn't match type of element 'usercontrol'.
and doesn't apply neither ucstyle nor mystyle in xaml viewer in visual studio, , doesn't draw child usercontrols properly. didn't expect solution run properly, did!
now questions are:
- why show these errors in design-time while runs properly?
- how rid of these errors in design-time? (i cleaned, , re-built solution, , restarted visual studio, , none of these worked)
- what's best practice deal `usercontrol` visual states in such situation in mvvm?
- what's best practice bind dependencyproperty of usercontrol property in it's viewmodel in mvvm?
i'm using visual studio 2012.
the wpf designer nefarious showing bogus errors @ design time. can't ignore them.
visual states concern of ui, , therefore should contained within ui. mvvm does not mean no codebehind. use codebehind ui tasks, , put business logic in view models.
your question suggests you're creating custom view models hold view logic user controls. seriously, don't that. that'll in trouble down road. interferes how databinding designed work.
there no "best practice" binding user control elements properties defined on surface. depends. using style seems odd, however. can give root of usercontrol x:name="root" , use elementname=root in binding.
an example of binding within usercontrol property defined on usercontrol (taken old prototype)...
here's usercontrol designed add or delete list of stuff.
- dependencyproperties defined on usercontrol
- bindings within usercontrol bind these properties
i don't guarantee works, illustrate how it's done:
public partial class itemseditor : usercontrol { #region items public static readonly dependencyproperty itemsproperty = dependencyproperty.register( "items", typeof(ienumerable<item>), typeof(itemseditor), new uipropertymetadata(null)); public ienumerable<item> items { { return (ienumerable<item>)getvalue(itemsproperty); } set { setvalue(itemsproperty, value); } } #endregion #region additem public static readonly dependencyproperty additemproperty = dependencyproperty.register( "additem", typeof(icommand), typeof(itemseditor), new uipropertymetadata(null)); public icommand additem { { return (icommand)getvalue(additemproperty); } set { setvalue(additemproperty, value); } } #endregion #region removeitem public static readonly dependencyproperty removeitemproperty = dependencyproperty.register( "removeitem", typeof(icommand), typeof(itemseditor), new uipropertymetadata(null)); public icommand removeitem { { return (icommand)getvalue(removeitemproperty); } set { setvalue(removeitemproperty, value); } } #endregion public itemseditor() { initializecomponent(); } } it lists bunch of things, can add new thing or delete thing list. here's bindings in xaml
<usercontrol x:class="lolprototype.itemseditor" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:t="clr-namespace:ucsandicommands" x:name="root"> <usercontrol.resources> <datatemplate datatype="{x:type t:item}"> <stackpanel orientation="horizontal"> <button command="{binding removeitem, elementname=root}" commandparameter="{binding}">remove</button> <textbox text="{binding name}" width="100"/> </stackpanel> </datatemplate> </usercontrol.resources> <stackpanel> <button command="{binding additem, elementname=root}">add</button> <itemscontrol itemssource="{binding items, elementname=root}" /> </stackpanel> </usercontrol> obviously, can define datatemplates outside list in ancestor's resources. point show how elementname bindings can used bind against properties defined in usercontrol.
Comments
Post a Comment