WinUI 3 中的UserControl:如何设置按钮的“Command”属性?

问题描述 投票:0回答:1

this帖子一样,我想创建一个由多个控件组成的用户控件,这些控件将在我的应用程序中的多个位置使用。就像其他帖子一样,命令栏中的按钮需要触发特定于其用途的事件/命令。这一切都很好,除了在某些情况下,我希望使用

Command
属性在实现控件的页面的
ViewModel
中触发 IRelay 命令,而不是使用
Click
事件。我使用按钮的 XAML
Command
属性碰壁了。

我的做法可能完全错误,但这就是我所拥有的和我陷入困境的地方。

用于实现自定义控件的

Page
XAML 绑定到
ViewModel
中的 IRelay 命令。未找到用户控件后面代码中的
ShowPropertiesCommand
IRelay 命令。

    <corecontrols:MyTreeView
        ...
        ShowPropertiesCommand="{x:Bind ViewModel.ShowPropertiesCommand}"
        TreeViewItemSource="{x:Bind ViewModel.Nodes, Mode=OneWay}" />

UserControl
XAML 绑定到后面代码中的 ShowPropertiesCommand IRelay 命令。

<UserControl x:Class="Core.UI.Controls.MyTreeView" ...>
    ...
        <CommandBar>
            ...
            <AppBarElementContainer>
                <Button
                    x:Name="CB_NodeProperties"
                    Command="{x:Bind ShowPropertiesCommand}"
                    ... />
            </AppBarElementContainer>
        </CommandBar>
    ...
</UserControl>

用户控件代码后面的代码。执行 ExecuteShowPropertiesCommand 是我陷入困境的另一个地方。如何让实现在实现用户控件的页面的 ViewModel 中运行命令?

    public MyTreeView()
    {
        this.InitializeComponent();
        ShowPropertiesCommand = new RelayCommand<object>(ExecuteShowPropertiesCommand);
    }
    public IRelayCommand ShowPropertiesCommand;

    private void ExecuteShowPropertiesCommand(object obj)
    {
        //WHAT TO PUT HERE??
    }
c# user-controls winui-3
1个回答
0
投票

您应该为此创建一个 DependencyProperty

让我向您展示一个简单的例子:

**SomeUserControl.xaml.cs

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System.Windows.Input;

namespace WinUIApp1;

public sealed partial class SomeUserControl : UserControl
{
    public static readonly DependencyProperty SomeCommandProperty = DependencyProperty.Register(
        nameof(SomeCommand),
        typeof(ICommand),
        typeof(SomeUserControl),
        new PropertyMetadata(default));

    public SomeUserControl()
    {
        InitializeComponent();
    }

    public ICommand SomeCommand
    {
        get => (ICommand)GetValue(SomeCommandProperty);
        set => SetValue(SomeCommandProperty, value);
    }
}

**SomeUserControl.xaml

<UserControl
    x:Class="WinUIApp1.SomeUserControl"
    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:WinUIApp1"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <CommandBar>
        <AppBarElementContainer>
            <Button
                Command="{x:Bind SomeCommand, Mode=OneWay}"
                Content="Click" />
        </AppBarElementContainer>
    </CommandBar>
</UserControl>

然后你可以像这样绑定命令:

**SomePage.xaml

<Page
    x:Class="WinUIApp1.SomePage"
    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:WinUIApp1"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
    mc:Ignorable="d">

    <local:SomeUserControl SomeCommand="{x:Bind ViewModel.DoSomeTaskCommand}" />

</Page>

**SomePage.xaml.cs

public sealed partial class SomePage : Page
{
    public Shell()
    {
        InitializeComponent();
    }

    public SomeViewModel ViewModel { get; } = new();
}

SomePageViewModel.cs

public partial class SomeViewModel : ObservableObject
{
    // The CommunityToolkit.Mvvm's source generator 
    // will generate a 'DoSomeTaskCommand' IRelayCommand for you.
    [RelayCommand]
    private void DoSomeTask()
    {
        // Do some task here...
    }
}

注意

ObservableObjectObservableProperty 来自 CommunityToolkit.Mvvm NuGet 包。

© www.soinside.com 2019 - 2024. All rights reserved.