0

I'm making a simple ListView with WinUI and Microsoft.Toolkit.Mvvm based on TemplateStudio for WinUI.

I try to achieve a simple ListView that contains fruits names, a 2nd ListView to get SelectedItems from the first one and finally a TextBox with count of selected items.

enter image description here

MainPage.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>

MainViewModel.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());
        }
    }
}

The GetSelectedFruitsMethod is successfully started but the parameter IList selectedFruits in GetSelectedFruitsMethod is always null and I can't figure out how to get the SelectedItems parameter from the View even if I passed it as CommandParameter in XAML.

Thanks and regards.

1 Answer 1

1

I finally got the answer by myself with the full MVVM way.

To retrieve SelectedItems from first ListView, there was just to set CommandParameter="{x:Bind LvwFruits.SelectedItems}" and not {Binding SelectedItems, ElementName=LvwFruits} and to replace IList by IList<object>.

MainPage.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" BorderThickness="1">
            <i:Interaction.Behaviors>
                <core:EventTriggerBehavior EventName="SelectionChanged">
                    <core:InvokeCommandAction Command="{x:Bind ViewModel.GetSelectedFruits, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" CommandParameter="{x:Bind LvwFruits.SelectedItems}"/>
                </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, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" CanDragItems="True" CanReorderItems="True" AllowDrop="True" SelectionMode="Single" BorderBrush="#212121" BorderThickness="1"/>
        <StackPanel Grid.Row="4" Orientation="Horizontal">
            <TextBlock Text="Count selected fruits : " VerticalAlignment="Center"/>
            <TextBox Text="{x:Bind ViewModel.CountSelectedCommands, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Margin="5,0,0,0" Width="10"/>
        </StackPanel>
    </Grid>
</Page>

MainViewModel.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;

    private ObservableCollection<string> listSelectedFruits;
    public ObservableCollection<string> ListSelectedFruits
    {
        get => listSelectedFruits;
        set => SetProperty(ref listSelectedFruits, value);
    }

    private int countSelectedCommands;
    public int CountSelectedCommands
    {
        get => countSelectedCommands;
        set => SetProperty(ref countSelectedCommands, value);
    }

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


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

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

        ListFruits = fruits;
    }

    private void GetSelectedFruitsMethod(IList<object> selectedFruits)
    {
        if (selectedFruits != null)
        {
            var selected = new ObservableCollection<string>();
            foreach (var item in selectedFruits)
            {
                selected.Add(item.ToString());
                Debug.WriteLine("Selected fruit : " + item.ToString());
            }
            ListSelectedFruits = selected;
            CountSelectedCommands = selected.Count;
        }
        else
        {
            Debug.WriteLine(@"/!\  NO SELECTED FRUITS /!\");
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.