Я хотел бы получить доступ к свойствам самой ViewModel, которые не обязательно являются частью свойств коллекции, которую я использую.
Я попытался создать класс, который имеет все свойства, которые я хочу вместе, как пакет. Но природа этого приложения требует общего свойства, к которому могут получить доступ все объекты.
Допустим, у меня есть следующее:
<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>
Как привязать кнопку, которая является элементом GridView, к команде ViewModel?
Пожалуйста, поделитесь фрагментом кода, который вы используете сейчас. Будет полезно знать ваши требования.
Только что добавил код @AndrewKeepCoding
Вам нужно назвать Page
и использовать это имя для привязки вашей команды ViewModel.
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
Я использую пакет NuGet CommunityToolkit.Mvvm, но он не имеет отношения к вашей проблеме.
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()
{
}
}
Для реализации этого можно использовать Xaml Behavior SDK.
MainPage.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
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;
}
}
Было бы легче понять вашу проблему с некоторым кодом.