首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >WinUI 3 ListView -如何在ListView中以编程方式选择项目?

WinUI 3 ListView -如何在ListView中以编程方式选择项目?
EN

Stack Overflow用户
提问于 2022-11-16 06:43:54
回答 2查看 46关注 0票数 0

如果用户与代码后面添加/删除的列表视图交互,那么我们有一个可观察的集合SelectedPartys

代码语言:javascript
运行
复制
<ListView
    x:Name="LV_Partys"
    IsMultiSelectCheckBoxEnabled="True"
    ItemsSource="{x:Bind ViewModel.PartysOC, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
    SelectionChanged="LV_Partys_SelectionChanged"
    SelectionMode="Extended">

    <ListView.ItemTemplate>
        <DataTemplate>

            <Grid Margin="0">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>

                <StackPanel Grid.Row="0" Orientation="Horizontal">
                    <TextBlock Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" TextWrapping="NoWrap" />
                </StackPanel>

            </Grid>

        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>
代码语言:javascript
运行
复制
private ObservableCollection<Party> partysOC;
public ObservableCollection<Party> PartysOC
{
    get => partysOC;
    set => Set(ref partysOC, value);
}

private void LV_Partys_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var added_items = e.AddedItems.Cast<Party>().ToList();
    foreach (var item in added_items)
    {
        ViewModel.SelectedPartys.Add(item);
    }

    var removed_items = e.RemovedItems.Cast<Party>().ToList();
    foreach (var item in removed_items)
    {
        ViewModel.SelectedPartys.Remove(item);
    }

    ViewModel.SelectedPartyChanged();
}

我们需要将ListViews选择的项目保存在Db中,然后在ListView中恢复它们--预选的,要做到这一点,我相信我们需要通过编程来选择一个项目,我们如何做到这一点?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-11-16 09:11:22

由于无法绑定到SelectedItems,因此可能需要创建从ListView派生的控件

CustomListView.cs

代码语言:javascript
运行
复制
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Data;
using Windows.Foundation.Collections;

namespace ListViews;

public class CustomListView : ListView
{
    public static readonly DependencyProperty SelectedItemsSourceProperty = DependencyProperty.Register(
        nameof(SelectedItemsSource),
        typeof(object),
        typeof(CustomListView),
        new PropertyMetadata(default, (d, e) =>
        {
            (d as CustomListView)?.UpdateSelectedItemsSource();
        }));

    public object SelectedItemsSource
    {
        get => (object)GetValue(SelectedItemsSourceProperty);
        set => SetValue(SelectedItemsSourceProperty, value);
    }

    private CollectionViewSource? SelectedItemsSourceViewSource { get; set; }

    private ICollectionView? SelectedItemsSourceView { get; set; }

    private void UpdateSelectedItemsSource()
    {
        if (SelectedItemsSourceView is not null)
        {
            SelectedItemsSourceView.VectorChanged -= SelectedItemsSourceView_VectorChanged;
        }

        SelectedItemsSourceViewSource = new()
        {
            Source = SelectedItemsSource
        };

        SelectedItemsSourceView = SelectedItemsSourceViewSource.View;
        SelectedItemsSourceView.VectorChanged += SelectedItemsSourceView_VectorChanged;
    }

    private void SelectedItemsSourceView_VectorChanged(IObservableVector<object> sender, IVectorChangedEventArgs @event)
    {
        switch (@event.CollectionChange)
        {
            case CollectionChange.Reset:
                SelectedItems.Clear();
                break;

            case CollectionChange.ItemInserted:
                if (SelectedItemsSourceView?.Count >= @event.Index)
                {
                    SelectedItems.Add(SelectedItemsSourceView[(int)@event.Index]);
                }
                break;

            case CollectionChange.ItemRemoved:
                if (SelectedItemsSourceView?.Count >= @event.Index)
                {
                    SelectedItems.Remove(SelectedItemsSourceView[(int)@event.Index]);
                }
                break;

            case CollectionChange.ItemChanged:
                break;

            default:
                break;
        }
    }
}

像这样使用它:

MainPage.xaml

代码语言:javascript
运行
复制
<local:CustomListView
    ItemsSource="{x:Bind ViewModel.Items, Mode=OneWay}"
    SelectedItemsSource="{x:Bind ViewModel.SelectedItems, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
    SelectionMode="Multiple">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="local:Item">
            <TextBlock Text="{x:Bind Id}" />
        </DataTemplate>
    </ListView.ItemTemplate>
</local:CustomListView>
票数 1
EN

Stack Overflow用户

发布于 2022-11-16 11:57:11

在WinUI 3 ListView上有一个名为YourListView.SelectRange()的方法

它在xaml的ListView上是不可用的,所以我通过MVVM消息调用在后面的代码中调用它。

文件后面的视图代码

代码语言:javascript
运行
复制
public CodeBehindConstructor()
{
    this.InitializeComponent();

    // Rx ListView Select items
    WeakReferenceMessenger.Default.Register<Msg_ListView_SelectItems>(this, (r, msg) =>
    {
        SelectParty(msg.Start, msg.Length);
    });
}


public void SelectParty(int start, uint length)
{
    Debug.WriteLine($"SelectParty  start {start}   len {length}");
    LV_Partys.SelectRange(new ItemIndexRange(start, length));
}

The ViewModel

代码语言:javascript
运行
复制
    // Select 1st Party 
    WeakReferenceMessenger.Default.Send(new Msg_ListView_SelectItems { Start = 0, Length = 1});// Start is 0 based, Length isnt it starts at 1

    // Select 2nd Party 
    WeakReferenceMessenger.Default.Send(new Msg_ListView_SelectItems { Start = 1, Length = 1 });

Msg_ListView_SelectItems类

代码语言:javascript
运行
复制
public class Msg_ListView_SelectItems
{
    public int Start { get; set; }
    public uint Length { get; set; }
}

如果您的ListViews选择模式是MultipleExtended,那么.SelectRange()将选择一个连续的许多项,因此您可以对不按顺序顺序的项目多次调用SelectRange

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74456195

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档