XAML 用WinUI3和Microsoft.Toolkit.mvvm实现列表视图选定项

wi3ka0sx  于 2022-12-16  发布在  其他
关注(0)|答案(1)|浏览(193)

我在TemplateStudio for WinUI的基础上用WinUIMicrosoft.Toolkit.Mvvm创建了一个简单的ListView
我尝试实现一个包含水果名称的简单ListView,第二个ListView从第一个SelectedItems获得SelectedItems,最后一个TextBox包含选定项的计数。

主页.xaml

<Page
    x:Class="ListViewWinUISample.Views.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:i="using:Microsoft.Xaml.Interactivity"
    xmlns:core="using:Microsoft.Xaml.Interactions.Core"
    mc:Ignorable="d">

    <Grid x:Name="ContentArea" Margin="20">
        <Grid.RowDefinitions>
            <RowDefinition Height="25" />
            <RowDefinition Height="150" />
            <RowDefinition Height="25" />
            <RowDefinition Height="150" />
            <RowDefinition Height="30" />
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" Text="Fruits list :" Style="{StaticResource PageTitleStyle}" />
        <ListView Grid.Row="1" x:Name="LvwFruits" ItemsSource="{x:Bind ViewModel.ListFruits}" BorderBrush="#212121" SelectionMode="Multiple">
            <i:Interaction.Behaviors>
                <core:EventTriggerBehavior EventName="SelectionChanged">
                    <core:InvokeCommandAction Command="{x:Bind ViewModel.GetSelectedFruits}" CommandParameter="{Binding SelectedItems, ElementName=LvwFruits}"/>
                </core:EventTriggerBehavior>
            </i:Interaction.Behaviors>
        </ListView>
        <TextBlock Grid.Row="2" Text="Selected fruits :" Style="{StaticResource PageTitleStyle}" />
        <ListView Grid.Row="3" x:Name="LvwSelectedFruits" ItemsSource="{x:Bind ViewModel.ListSelectedFruits}" BorderBrush="#212121"/>
        <StackPanel Grid.Row="4" Orientation="Horizontal">
            <TextBlock Text="Count selected fruits : " VerticalAlignment="Center"/>
            <TextBox Text="{Binding SelectedItems.Count, ElementName=LvwFruits}" VerticalAlignment="Center"/>
        </StackPanel>
    </Grid>
</Page>

主视图模型.cs

using System.Collections;
using System.Collections.ObjectModel;
using System.Diagnostics;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace ListViewWinUISample.ViewModels;

public class MainViewModel : ObservableRecipient
{
    public List<string> ListFruits;
    public List<string> ListSelectedFruits;

    public RelayCommand<IList> GetSelectedFruits { get; set; }

    public MainViewModel()
    {
        GetSelectedFruits = new RelayCommand<IList>(GetSelectedFruitsMethod);

        var fruits = new List<string>
        {
            "Apple",
            "Banana",
            "Strawberry"
        };

        ListFruits = fruits;
    }

    private void GetSelectedFruitsMethod(IList selectedFruits)
    {
        Debug.WriteLine("Command successfully executed");
        var listSelectedFruits = new List<string>();
        foreach (var item in selectedFruits)
        {
            listSelectedFruits.Add(item.ToString());
            Debug.WriteLine("selected fruit : " + item.ToString());
        }
    }
}

GetSelectedFruitsMethod已成功启动,但GetSelectedFruitsMethod中的参数IList selectedFruits始终为null,即使我在XAML中将其作为CommandParameter传递,我也不知道如何从视图中获取SelectedItems参数。
谢谢,问候。

xytpbqjk

xytpbqjk1#

您可以像这样创建自定义控件:

列表视图示例.cs

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System.Collections;
using System.Collections.Generic;

namespace ListViews;

public class ListViewEx : ListView
{
    public ListViewEx() : base()
    {
        this.SelectionChanged += ListViewEx_SelectionChanged;
    }

    public new IList SelectedItems
    {
        get => (IList)GetValue(SelectedItemsProperty);
        set => SetValue(SelectedItemsProperty, value);
    }

    public static readonly DependencyProperty SelectedItemsProperty = DependencyProperty.Register(
        nameof(SelectedItems),
        typeof(IList),
        typeof(ListViewEx),
        new PropertyMetadata(new List<object>()));

    private void ListViewEx_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        foreach (object item in e.RemovedItems)
        {
            SelectedItems.Remove(item);
        }

        foreach (object item in e.AddedItems)
        {
            SelectedItems.Add(item);
        }
    }
}

并像这样使用它:

主页.xaml

<Grid RowDefinitions="Auto,*,*">
    <StackPanel
        Grid.Row="0"
        Orientation="Horizontal">
        <NumberBox
            x:Name="LoadingItemsCount"
            Value="1000" />
        <Button
            Command="{x:Bind ViewModel.LoadItemsCommand}"
            CommandParameter="{x:Bind LoadingItemsCount.Value, Mode=OneWay}" />
    </StackPanel>
    <local:ListViewEx
        Grid.Row="1"
        ItemsSource="{x:Bind ViewModel.Items, Mode=OneWay}"
        SelectedItems="{x:Bind ViewModel.SelectedItems, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
        SelectionMode="Multiple">
        <local:ListViewEx.Header>
            <TextBlock>
                <Run Text="Items: " />
                <Run Text="{x:Bind ViewModel.Items.Count, Mode=OneWay}" />
            </TextBlock>
        </local:ListViewEx.Header>
    </local:ListViewEx>
    <ListView
        Grid.Row="2"
        ItemsSource="{x:Bind ViewModel.SelectedItems, Mode=OneWay}">
        <ListView.Header>
            <TextBlock>
                <Run Text="Selected items: " />
                <Run Text="{x:Bind ViewModel.SelectedItems.Count, Mode=OneWay}" />
            </TextBlock>
        </ListView.Header>
    </ListView>
</Grid>

主页.xaml.cs

[ObservableObject]
public partial class MainPageViewModel
{
    [ObservableProperty]
    private ObservableCollection<string> items = new();

    [ObservableProperty]
    private ObservableCollection<string> selectedItems = new();

    public MainPageViewModel()
    {
        var ilist = items as IList;
    }

    [RelayCommand]
    private void LoadItems(double itemsCount)
    {
        for (int i = 0; i < itemsCount; i++)
        {
            Items.Add(i.ToString());
        }
    }
}

相关问题