Search code examples
uwpwinui-3winui

Is it possible to not define a DataType on a GridView?


I would like to access properties of the ViewModel itself, that are not necessarily part of the properties of the collection I am using.

I've tried creating a class that has all properties I want together, as a package. But the nature of this application requires a shared property that all entities can access.

Let's say I have the following:

<GridView
    ItemClick="{x:Bind ViewModel.GridView_ItemClick}"
    ItemsSource="{x:Bind ViewModel.GridViewGames, Mode=OneWay}">
    <GridView.ItemTemplate>
        <DataTemplate x:DataType="models:GameModel">
                <ScrollViewer VerticalScrollBarVisibility="Visible">
                    <StackPanel Orientation="Vertical">
                        <TextBlock Style="{StaticResource SubtitleTextBlockStyle}" Text="{Binding Name}" />
                        <TextBlock
                            Style="{StaticResource BodyTextBlockStyle}"
                            Text="{Binding CallToAction}"
                            TextWrapping="Wrap" />
                        <Button Command="{BIND TO AN ICOMMAND FROM THE VIEWMODEL AND NOT THE GAMEMODEL}"/>
                    </StackPanel>
                </ScrollViewer>
        </DataTemplate>
    </GridView.ItemTemplate>
</GridView>

How would I bind the button, which is an item of the GridView, to a command of the ViewModel?


Solution

  • You need to name the Page and use that name to bind your ViewModel command.

    MainPage.xaml

    <Page
        x:Class="GridViews.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:models="using:GridViews"
        x:Name="ThisPage"
        Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
        mc:Ignorable="d">
    
        <Grid>
            <GridView ItemsSource="{x:Bind ViewModel.GridViewGames, Mode=OneWay}">
                <GridView.ItemTemplate>
                    <DataTemplate x:DataType="models:GameModel">
                        <ScrollViewer VerticalScrollBarVisibility="Visible">
                            <StackPanel Orientation="Vertical">
                                <TextBlock
                                    Style="{StaticResource SubtitleTextBlockStyle}"
                                    Text="{x:Bind Name}" />
                                <TextBlock
                                    Style="{StaticResource BodyTextBlockStyle}"
                                    Text="{x:Bind CallToAction}"
                                    TextWrapping="Wrap" />
                                <Button Command="{Binding ElementName=ThisPage, Path=ViewModel.TestCommand}" />
                            </StackPanel>
                        </ScrollViewer>
                    </DataTemplate>
                </GridView.ItemTemplate>
            </GridView>
        </Grid>
    </Page>
    

    MainPageViewModel.cs

    I'm using the CommunityToolkit.Mvvm NuGet package here but it's irrelevant to your issue.

    using CommunityToolkit.Mvvm.ComponentModel;
    using CommunityToolkit.Mvvm.Input;
    using System.Collections.ObjectModel;
    
    namespace GridViews;
    
    public class GameModel
    {
        public string Name { get; set; } = string.Empty;
        public string CallToAction { get; set; } = string.Empty;
    }
    
    public partial class MainPageViewModel : ObservableObject
    {
        [ObservableProperty]
        private ObservableCollection<GameModel> gridViewGames = new()
        {
            new GameModel() {Name="Name A", CallToAction="Call To Action A" },
            new GameModel() {Name="Name B", CallToAction="Call To Action B" },
            new GameModel() {Name="Name C", CallToAction="Call To Action C" },
        };
    
        [RelayCommand]
        private void Test()
        {
        }
    }