Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HubSection with compiled binding

I'm trying to grasp the new compiled bindings, but right at the start I get stopped by this simple problem.

I have Hub control with one HubSection. The content of this section is an ItemsControl that needs to bind to view models' observable collection. I can't get this binding to work as I expect it to.

<Pivot x:Name="rootPivot" Style="{StaticResource TabsStylePivotStyle}">
    <PivotItem>
        <Hub>
            <HubSection Header="News">
                <DataTemplate x:DataType="local:HomePage">
                    <ItemsControl ItemsSource="{x:Bind ViewModel.NewsItems, Mode=OneWay}" />

ViewModel property is just a property and is instantiated before InitializeComponents() call. NewsItems is observable collection inside view model that is filled after the page has loaded - asynchronously (web request).

What am I doing wrong here?

EDIT: Code-behind

HomePage.xaml.cs

/// <summary>
/// Home pag view.
/// </summary>
public sealed partial class HomePage : Page
{
    /// <summary>
    /// Initializes a new instance of the <see cref="HomePage"/> class.
    /// </summary>
    public HomePage()
    {
        // Retrieve view model
        this.ViewModel = ViewModelResolver.Home;

        // Trigger view model loaded on page loaded
        this.Loaded += (sender, args) => this.ViewModel.LoadedAsync();

        this.InitializeComponent();
    }

    /// <summary>
    /// Gets the view model.
    /// </summary>
    /// <value>
    /// The view model.
    /// </value>
    public IHomeViewModel ViewModel { get; }
}

HomePageViewModel.cs

/// <summary>
/// Home view model.
/// </summary>
public sealed class HomeViewModel : IHomeViewModel
{
    /// <summary>
    /// Occurs on page loaded.
    /// </summary>
    public async Task LoadedAsync()
    {
        // Retrieve news items
        var news = await new NewsService().GetNewsAsync();
        foreach (var newsItem in news)
            this.NewsItems.Add(newsItem);
    }

    /// <summary>
    /// Gets the news items.
    /// </summary>
    /// <value>
    /// The news items.
    /// </value>
    public ObservableCollection<IFeedItem> NewsItems { get; } = new ObservableCollection<IFeedItem>();
}
like image 247
Aleksandar Toplek Avatar asked Sep 28 '22 01:09

Aleksandar Toplek


1 Answers

This is indeed an interesting question. I guess the issue is that, unlike typical DataTemplate like the following (see its parent ListView is binding to some known data Model.Items)

<ListView ItemsSource="{x:Bind Model.Items}">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="model:Item">
            <Grid>
                <TextBlock Text="{x:Bind Name}" />
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

your top level DataTemplate however, doesn't know where the data comes from.

So the fix is to tell the HubSection to bind the right data - in this case, the HomePage.xaml.cs instance. So, try adding this to your Hub

<Hub DataContext="{x:Bind}">

Or simply add

this.InitializeComponent();
this.DataContext = this;

Either way should fix your issue.

like image 154
Justin XL Avatar answered Nov 15 '22 06:11

Justin XL