My my, look at this here:
<UserControl.DataContext>
<local:HabitacionControlVM/>
</UserControl.DataContext>
Someone sold you a bill of dirty, filthy, goods. Probably one of those jerks who run around telling people DataContext = this;
is a good idea.
Sorry, tangent. Now look at this:
<ctr:HabitacionControl
Width="70"
Height="140"
Ubicacion="{Binding}"/>
What is that I'm seeing? Is that a pseudo-DataContext property? That's a pseudo-DataContext property. The problem is that the Binding
works against the object within the DataContext of the HabitacionControl
not its parent. And what's the DataContext of the HabitacionControl
?
<UserControl.DataContext>
<local:HabitacionControlVM/>
</UserControl.DataContext>
And that's why you don't create view models for your UserControls. You have broken how data binding works. The view model must flow down the visual tree through the DataContext. When you interrupt this flow, you get fail.
Let me ask you--does a TextBox have a TextBoxViewModel? No. It has a Text
property that you bind to. How do you bind to it? Your view model flows into TextBox.DataContext
, thus allowing you to bind properties of your view model to properties exposed on the TextBox.
There are other hacky ways to get around this, but the best solution is to not get yourself into this situation in the first place.
You need to ditch that HabitacionControlVM
and expose DependencyProperties on the surface of your UserControl that your view model can bind against, providing whatever your UserControl needs in order to function. Place your UI logic in the codebehind of HabitacionControl
.
No, this doesn't break MVVM. UI logic is fine in the codebehind.
If your HabitacionControlVM
is performing heavy lifting that really shouldn't be in the codebehind, then just refactor it into classes that your codebehind calls into.
People think the UserControlViewModel anti-pattern is how it should be done. It really isn't. Good luck.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…