在WinUI 3应用程序中,使用CommunityToolkit.Mvvm,我有一个XXXPage,它有一个ListDetailsView。
我为ListDetailsView DetailsTemplate定义了一个DetailsTemplate,其中包含一个用户控件: XXXDetailControl。
我试图将XXXDetailControl的XXXDetailControl事件绑定到页面的ViewModel InstallCommand,但没有成功。
<DataTemplate x:Key="DetailsTemplate">
<Grid>
<views:XXXDetailControl
DetailMenuItem="{Binding}"
InstallClicked="{ ???? }" />
</Grid>
...
</DataTemplate>
如何设置此绑定,以便将DataTemplate中定义的控件中的事件绑定到页面视图模型命令?如何设置此绑定,以便与事件一起发送选定的项?
XXXPage.xaml :
<Page
x:Class="XXXPage"
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:XXX.Models"
xmlns:views="using:XXX.Views"
xmlns:behaviors="using:XXX.Behaviors"
xmlns:controls="using:CommunityToolkit.WinUI.UI.Controls"
xmlns:viewmodels="using:XXX.ViewModels"
behaviors:NavigationViewHeaderBehavior.HeaderMode="Never"
mc:Ignorable="d">
<Page.Resources>
...
<DataTemplate x:Key="DetailsTemplate">
<Grid>
<views:XXXDetailControl
DetailMenuItem="{Binding}"
InstallClicked="{Binding ViewModel.InstallCommand, ElementName=?}" CommandParameter="{x:Bind (viewmodels:XXXDetailViewModel)}" />
</Grid>
...
</DataTemplate>
</Page.Resources>
<Grid x:Name="ContentArea">
...
<controls:ListDetailsView
x:Uid="ListDetails"
x:Name="ListDetailsViewControl"
DetailsTemplate="{StaticResource DetailsTemplate}"
ItemsSource="{x:Bind ViewModel.Items}"/>
</Grid>
</Page>
XXXPage.cs :
public sealed partial class XXXPage: Page
{
public XXXViewModel ViewModel
{
get;
}
public XXXPage()
{
ViewModel = App.GetService<XXXViewModel >();
InitializeComponent();
}
}
the XXXViewModel :
public class XXXViewModel : ObservableRecipient, INavigationAware
{
private XXXDetailViewModel? _selected;
public XXXDetailViewModel? Selected
{
get => _selected;
set
{
SetProperty(ref _selected, value);
}
}
public ObservableCollection<XXXDetailViewModel> Items { get; private set; } = new ObservableCollection<XXXDetailViewModel>();
public ICommand InstallCommand;
}
发布于 2022-10-14 12:52:00
如果您可以在用户控件中使用Command
和CommandParameter
,则可以这样做。
DetailsControl.xaml.cs
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System.Windows.Input;
namespace CustomControlEvent;
public sealed partial class DetailControl : UserControl
{
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
nameof(Text),
typeof(string),
typeof(DetailControl),
new PropertyMetadata(default));
public static readonly DependencyProperty ClickCommandProperty = DependencyProperty.Register(
nameof(ClickCommand),
typeof(ICommand),
typeof(DetailControl),
new PropertyMetadata(default));
public static readonly DependencyProperty ClickCommandParameterProperty = DependencyProperty.Register(
nameof(ClickCommandParameter),
typeof(object),
typeof(DetailControl),
new PropertyMetadata(default));
public DetailControl()
{
this.InitializeComponent();
}
public object ClickCommandParameter
{
get => (object)GetValue(ClickCommandParameterProperty);
set => SetValue(ClickCommandParameterProperty, value);
}
public string Text
{
get => (string)GetValue(TextProperty);
set => SetValue(TextProperty, value);
}
public ICommand ClickCommand
{
get => (ICommand)GetValue(ClickCommandProperty);
set => SetValue(ClickCommandProperty, value);
}
}
DetailsControl.xaml
<UserControl
x:Class="CustomControlEvent.DetailControl"
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:local="using:CustomControlEvent"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<Button
Command="{x:Bind ClickCommand, Mode=OneWay}"
CommandParameter="{x:Bind ClickCommandParameter, Mode=OneWay}"
Content="{x:Bind Text, Mode=OneWay}" />
</Grid>
</UserControl>
MainPageViewModel.cs
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System.Collections.ObjectModel;
namespace CustomControlEvent;
public partial class MainPageViewModel : ObservableObject
{
[RelayCommand]
private void Run(object commandParameter)
{
}
[ObservableProperty]
private ObservableCollection<DetailsViewModel> items = new()
{
new DetailsViewModel() { Details = "A" },
new DetailsViewModel() { Details = "B" },
new DetailsViewModel() { Details = "C" },
};
}
MainPage.xaml.cs
using Microsoft.UI.Xaml.Controls;
namespace CustomControlEvent;
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
public MainPageViewModel ViewModel { get; } = new();
}
MainPage.xaml
此页面名为“DataTemplate. ThisPage”,以便从
<Page
x:Class="CustomControlEvent.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:local="using:CustomControlEvent"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="ThisPage"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
<StackPanel>
<StackPanel.Resources>
<DataTemplate
x:Key="DetailsTemplate"
x:DataType="local:DetailsViewModel">
<Grid>
<local:DetailControl
ClickCommand="{Binding ElementName=ThisPage, Path=ViewModel.RunCommand}"
ClickCommandParameter="{x:Bind}"
Text="{x:Bind Details, Mode=OneWay}" />
</Grid>
</DataTemplate>
</StackPanel.Resources>
<ListView
ItemTemplate="{StaticResource DetailsTemplate}"
ItemsSource="{x:Bind ViewModel.Items, Mode=OneWay}" />
</StackPanel>
</Page>
发布于 2022-10-19 12:27:39
你试过像这样给Page
一个Name
吗?
<Page ...
Name="thePage">
<Page.Resources>
...
<DataTemplate x:Key="DetailsTemplate">
<Grid>
<views:XXXDetailControl
DetailMenuItem="{Binding}"
InstallClicked="{Binding ViewModel.InstallCommand, ElementName=thePage}" ... />
</Grid>
...
</DataTemplate>
</Page.Resources>
这似乎适用于ListView
。
https://stackoverflow.com/questions/74067709
复制相似问题