MAUI CollectionView SelectedItem not updating

huangapple go评论144阅读模式
英文:

MAUI CollectionView SelectedItem not updating

问题

根据文档(https://learn.microsoft.com/en-us/dotnet/maui/user-interface/controls/collectionview/selection),SelectedItem是双向绑定的,但当我点击CollectionView中的项目时似乎没有任何反应。

出于调试目的,我已经添加了一个按钮来随机选择一个项目,这是有效的,所以我认为我在集合绑定方面可能有问题,或者需要进行更多的连接。

View

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Maui.Views.WorldPage"
             xmlns:viewmodels="clr-namespace:Maui.ViewModels"
             x:DataType="viewmodels:WorldViewModel"
             xmlns:models="clr-namespace:Maui.Models"
             Title="WorldPage"
             xmlns:controls="clr-namespace:Maui.Controls">
    <StackLayout>
        <controls:AreaDetailsView Area="{Binding SelectedArea}"/>
        <CollectionView ItemsSource="{Binding Areas}"
                        ItemsLayout="VerticalGrid, 7"
                        SelectionMode="Single"
                        SelectedItem="{Binding SelectedArea}">
            <CollectionView.ItemTemplate>
                <DataTemplate x:DataType="models:Area">
                    <controls:AreaView Area="{Binding .}"/>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
        <Button Text="Select Random"
                Command="{Binding SelectRandomCommand}"/>
    </StackLayout>
</ContentPage>

ViewModel

public partial class WorldViewModel : ObservableObject
{
    public ObservableCollection<Area> Areas { get; set; }
    [ObservableProperty]
    public Area selectedArea;

    private readonly WorldService _worldService;
    private readonly World _world;

    public WorldViewModel(WorldService worldService)
    {
        _worldService = worldService;
        _world = _worldService.Get(0);
        Areas = new ObservableCollection<Area>(_world.Areas);
        SelectedArea = _world.Areas.Single(x => x.X == 1 && x.Y == 1);
    }
    [RelayCommand]
    void SelectRandom()
    {
        var random = new Random().Next(Areas.Count);
        SelectedArea = Areas[random];
    }
}

上面的自定义控件在CollectionView上方显示所选区域的更多详细信息。它与SelectedArea属性绑定。

我希望当我点击一个区域时,显示视图会更新为我点击的区域。

应用程序的屏幕截图以帮助理解。

MAUI CollectionView SelectedItem not updating

英文:

According to the documentation (https://learn.microsoft.com/en-us/dotnet/maui/user-interface/controls/collectionview/selection) SelectedItem is two way binding but when I click on a item in the CollectionView it seems that nothing happen.

For debugging purposes I have added a button to randomly selecting an item and this is working, so I believe I have a problem in the collection binding or I need to do more wiring.

View

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Maui.Views.WorldPage"
             xmlns:viewmodels="clr-namespace:Maui.ViewModels"
             x:DataType="viewmodels:WorldViewModel"
             xmlns:models="clr-namespace:Maui.Models"
             Title="WorldPage"
             xmlns:controls="clr-namespace:Maui.Controls">
    <StackLayout>
        <controls:AreaDetailsView Area="{Binding SelectedArea}"/>
        <CollectionView ItemsSource="{Binding Areas}"
                        ItemsLayout="VerticalGrid, 7"
                        SelectionMode="Single"
                        SelectedItem="{Binding SelectedArea}">
            <CollectionView.ItemTemplate>
                <DataTemplate x:DataType="models:Area">
                    <controls:AreaView Area="{Binding .}"/>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
        <Button Text="Select Random"
                Command="{Binding SelectRandomCommand}"/>
    </StackLayout>
</ContentPage>

ViewModel

public partial class WorldViewModel : ObservableObject
{
    public ObservableCollection<Area> Areas { get; set; }
    [ObservableProperty]
    public Area selectedArea;

    private readonly WorldService _worldService;
    private readonly World _world;

    public WorldViewModel(WorldService worldService)
    {
        _worldService = worldService;
        _world = _worldService.Get(0);
        Areas = new ObservableCollection<Area>(_world.Areas);
        SelectedArea = _world.Areas.Single(x => x.X == 1 && x.Y == 1);
    }
    [RelayCommand]
    void SelectRandom()
    {
        var random = new Random().Next(Areas.Count);
        SelectedArea = Areas[random];
    }
}

The custom control above the collection view, display more details of the selected area. It's binded to SelectedArea property.

I would like that when I click on an area, the display view is updated with the one I clicked on.

Sceenshot of the app to help understanding.

MAUI CollectionView SelectedItem not updating

答案1

得分: 1

So I finally found an open bug In the MAUI repo that says CollectionView's SelectionChanged method cannot be triggered when tapping the item directly see https://github.com/dotnet/maui/issues/9567

这里终于找到一个在 MAUI 存储库中的开放性错误,它表示 在直接点击项目时无法触发 CollectionView 的 SelectionChanged 方法,请参见 https://github.com/dotnet/maui/issues/9567

It's on open bug that is affecting Android and will be fix later (it's in the backlog as of Aug 2023).

这是一个正在影响 Android 的未解决错误,将来会修复(截至 2023 年 8 月仍在待办事项中)。

The workaround is to not use Frame. So I change the data Template in my collection view

解决方法是不使用 Frame。 所以我更改了我的集合视图中的数据模板

            <CollectionView.ItemTemplate>
                <DataTemplate x:DataType="models:Area">
                    <controls:AreaView Area="{Binding .}"/>
                </DataTemplate>
            </CollectionView.ItemTemplate>

To not use Frame...I just used a StackLayout

为了不使用 Frame... 我只是使用了一个 StackLayout

<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Maui.Controls.AreaView"
             xmlns:converters="clr-namespace:Maui.Converters"
             x:Name="this">
    <ContentView.Resources>
        <converters:AreaTypeConverter x:Key="AreaTypeConverter" />
    </ContentView.Resources>
    <StackLayout BindingContext="{x:Reference this}" BackgroundColor="{Binding Area.Type, Converter={StaticResource AreaTypeConverter}}">
        <Label>
            <Label.FormattedText>
                <FormattedString>
                    <Span Text="("/>
                    <Span Text="{Binding Area.X}"/>
                    <Span Text=","/>
                    <Span Text="{Binding Area.Y}"/>
                    <Span Text=")"/>
                </FormattedString>
            </Label.FormattedText>
        </Label>
    </StackLayout>
</ContentView>
英文:

So I finally found an open bug In the MAUI repo that says CollectionView's SelectionChanged method cannot be triggered when tapping the item directly see https://github.com/dotnet/maui/issues/9567

It's on open bug that is affecting Android and will be fix later (it's in the backlog asof Aug 2023).

The workaround is to not use Frame. So I change the data Template in my collection view

            <CollectionView.ItemTemplate>
                <DataTemplate x:DataType="models:Area">
                    <controls:AreaView Area="{Binding .}"/>
                </DataTemplate>
            </CollectionView.ItemTemplate>

To not use Frame...I just used a StackLayout

<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Maui.Controls.AreaView"
             xmlns:converters="clr-namespace:Maui.Converters"
             x:Name="this">
    <ContentView.Resources>
        <converters:AreaTypeConverter x:Key="AreaTypeConverter" />
    </ContentView.Resources>
    <StackLayout BindingContext="{x:Reference this}" BackgroundColor="{Binding Area.Type, Converter={StaticResource AreaTypeConverter}}">
        <Label>
            <Label.FormattedText>
                <FormattedString>
                    <Span Text="("/>
                    <Span Text="{Binding Area.X}"/>
                    <Span Text=","/>
                    <Span Text="{Binding Area.Y}"/>
                    <Span Text=")"/>
                </FormattedString>
            </Label.FormattedText>
        </Label>
    </StackLayout>
</ContentView>

huangapple
  • 本文由 发表于 2023年8月5日 01:32:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/76838073.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定