Xaml Gridview Itemtemplate Not Binding to Control

XAML GridView ItemTemplate not binding to control

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.

Using x:Bind inside the GridView's ItemTemplate layout User Control in UWP

Well it's possible to use x:Bind in user controls, but you'll need to add some extra code behind.
I encountered the same problem in my project, you can see the result here : https://github.com/AppCreativity/Kliva/tree/master/src/Kliva/Controls

So what you need to do is, create a property in the code behind of your user control that points to the correct DataContext.
If you do that, you can use properties of that DataContext in the xaml of your control: for example:
Do note that in the constructor of your control you do need to add: DataContextChanged += (sender, args) => this.Bindings.Update(); because the datacontext will change depending on the page where your control is used!

Then on the page where you are placing this control, you'll also need to do the same to enable the x:bind to work.
You'll see this in my example on the MainPage.DeviceFamily-Mobile.xaml and MainPage.xaml.cs files.

Hope this helps.

GridView ItemClick event not working?

So finally as I deleted the following part from Book.xaml, the item click works fine:

<GridView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding name}" Margin="-12,0,0,0"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</GridView.GroupStyle>

I did not find out what caused the problem, but now it works.
Thank you for your help and time :)

XAML GridView template bind to item

Add a dependency property to the ChapterBox class, and then use a two-way binding in the XAML:

<local:ChapterBox Chapter="{Binding Mode=TwoWay}" />

The DP would look like this (assume you're using WPF, but it's similar for Silverlight):

public static readonly DependencyProperty ChapterProperty = 
DependencyProperty.Register("Chapter",
// property type
typeof(BibleChapter),
// property owner type
typeof(ChapterBox),
new UIPropertyMetadata(new PropertyChangedCallback(OnChapterChanged)));

public static void OnChapterChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
var chapterBox = (ChapterBox)sender;

VerseRichTextBuilder builder = new VerseRichTextBuilder();
var newValue = (Chapter)args.NewValue;
builder.Build(chapterBox.textBlock, newValue);
}

public BibleChapter Chapter
{
get { return (BibleChapter)GetValue(ChapterProperty); }
set { SetValue(ChapterProperty, value); }
}

Notice that the ChapterProperty DP is actually the binding source, while the view model property (BibleChapter) is the target. However, when you set Mode=TwoWay, it causes the property to update the source from the target.

Binding to custom control inside DataTemplate for ItemsControl

The problem is that you explicitly set the DataContext of your UserControl to itself:

DataContext="{Binding Mode=OneWay, RelativeSource={RelativeSource Self}}

Remove that assignment and write the ItemName binding like this:

<TextBlock Text="{Binding ItemName,
RelativeSource={RelativeSource AncestorType=UserControl}}"/>

or like this

<TextBlock Text="{Binding ItemName, ElementName=ItemRowControl}"/>


Related Topics



Leave a reply



Submit