XAML GridView ItemTemplate not binding to control

I have a GridView with an ItemTemplate that contains a custom control:

<GridView
    ItemsSource="{Binding Ubicaciones.Ubicaciones}">
    <GridView.ItemTemplate>
        <DataTemplate>
            <ctr:HabitacionControl
                Width="70"
                Height="140"
                Ubicacion="{Binding}"/>
        </DataTemplate>
    </GridView.ItemTemplate>
</GridView>

      

And here is my control:

<UserControl
        x:Class="MySln.Mucama.Controls.HabitacionControl"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:MySln.Mucama.Controls"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        d:DesignHeight="200"
        d:DesignWidth="97">
    <UserControl.DataContext>
        <local:HabitacionControlVM/>
    </UserControl.DataContext>
    <Grid>
        <RelativePanel>
            <Image x:Name="Puerta" Source="ms-appx:///Assets/Puerta.jpg"
                   Grid.RowSpan="5"/>
            <TextBlock Text="{Binding Ubicacion.StrNombreMesa,FallbackValue=####}"
                       HorizontalAlignment="Center"
                       VerticalAlignment="Center"
                       Foreground="AliceBlue"
                       FontWeight="ExtraBold"
                           RelativePanel.AlignHorizontalCenterWithPanel="True"/>
        </RelativePanel>
    </Grid>
</UserControl>

      

And his code is behind:

public sealed partial class HabitacionControl : UserControl
{
    public HabitacionControl()
    {
        this.InitializeComponent();
    }

    public MyClass Ubicacion
    {
        get { return (MyClass)GetValue(UbicacionProperty); }
        set { SetValue(UbicacionProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Ubicacion.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty UbicacionProperty =
        DependencyProperty.Register("Ubicacion", typeof(MyClass), typeof(HabitacionControl), new PropertyMetadata(new PropertyChangedCallback(OnUbicacionChanged)));

    private static void OnUbicacionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
       //...
    }
}

      

Now I need to bind each Ubicaciones.Ubicaciones to the UbicaciΓ³n property of my Customcontrol.

At runtime the gridview generates all my items, but the Ubicacion property binding never happens.

There are no warnings in the output window.

What am I missing? Or do it wrong?

+3


source to share


1 answer


My, look at it here:

<UserControl.DataContext>
    <local:HabitacionControlVM/>
</UserControl.DataContext>

      



Someone sold you a dirty, dirty merchandise bill. Probably one of those jerks that running around telling people DataContext = this;

is a good idea.

Sorry tangent. Now let's look at this:

<ctr:HabitacionControl 
    Width="70" 
    Height="140" 
    Ubicacion="{Binding}"/>

      

What do I see? Is this a pseudo-DataContext property? This property is pseudo-DataContext. The problem is what Binding

works against the object in the DataContext HabitacionControl

, not its parent . And what is DataContext HabitacionControl

?

<UserControl.DataContext>
    <local:HabitacionControlVM/>
</UserControl.DataContext>

      



And why don't you create view models for your UserControls. You have broken data binding. The view model must flow through the visual tree through the DataContext. When you interrupt this flow, you are rejected.

Let me ask you - does the TextBox have a TextBoxViewModel? Not. It has a property Text

that you are binding to. How do you contact him? Your view model flows into TextBox.DataContext

, which allows you to bind the properties of your view model to properties exposed in the TextBox.

There are other hacky ways to get around this, but the best solution is not to get into this situation in the first place.

You need to ditch that HabitacionControlVM

and expose DependencyProperties on the surface of your UserControl that your ViewModel can communicate with, ensuring whatever your needs the UserControl to function with. Put your UI logic in codebehind HabitacionControl

.

No, it doesn't break MVVM. The UI logic is great for code.

If yours HabitacionControlVM

is doing the heavy lifting that really shouldn't be in the code, then just reformat it into the classes you type into.

People think that the anti-pattern UserControlViewModel is how it should be done. This is really not the case. Good luck.

+6


source







All Articles