简体   繁体   English

是否可以不在 GridView 上定义数据类型?

[英]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.我想访问 ViewModel 本身的属性,这些属性不一定是我正在使用的集合的属性的一部分。

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?我如何将作为 GridView 项目的按钮绑定到 ViewModel 的命令?

You need to name the Page and use that name to bind your ViewModel command.您需要为Page命名并使用该名称来绑定您的 ViewModel 命令。

MainPage.xaml主页.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 MainPageViewModel.cs

I'm using theCommunityToolkit.Mvvm NuGet package here but it's irrelevant to your issue.我在这里使用CommunityToolkit.Mvvm NuGet 包,但这与您的问题无关。

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()
    {
    }
}

You could use Xaml Behaviior SDK to implement this.您可以使用Xaml Behaviior SDK来实现它。

MainPage.Xaml:主页.Xaml:

    <GridView x:Name="MyGridView"
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 x:Name="MyButton" Foreground="BurlyWood" FontSize="30" Content="{Binding Name}">
                            <Interactivity:Interaction.Behaviors>
                                <Core:EventTriggerBehavior EventName="Click" >
                                    <Core:InvokeCommandAction Command="{Binding DataContext.ViewModel.ButtonClickEvent, ElementName=MyGridView}" CommandParameter="{Binding}" />
                                </Core:EventTriggerBehavior>
                            </Interactivity:Interaction.Behaviors>
                        </Button>

                    </StackPanel>
                </ScrollViewer>
            </DataTemplate>
        </GridView.ItemTemplate>
    </GridView>

ViewModel.cs ViewModel.cs

  public class TestViewModel 
{
    public List<GameModel> GridViewGames = new List<GameModel>();

    //*****
    // your original code 
    //*****


    // add the command
    public ICommand ButtonClickEvent
    {
        get
        {
            return new CommadEventHandler<GameModel>((s) => this.DataProcessing(s));
        }

    }

    private void DataProcessing(GameModel data)
    {
        try
        {
            Debug.WriteLine(data);
        }
        catch (Exception ex)
        {
           
        }
    }
}

public class CommadEventHandler<T> : ICommand
{
    public event EventHandler CanExecuteChanged;

    public Action<T> action;
    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        this.action((T)parameter);
    }
    public CommadEventHandler(Action<T> action)
    {
        this.action = action;

    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM