CollectionView SelectedChangedCommand 执行多次 - .NET MAUI

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

我正在使用 CollectionView,我需要导航到 SelectedChangedCommand 上的新页面。 但是绑定到 SelectedChangedCommand 的命令对于单个选择执行多次。 我有一个嵌套的 CollectionView。对于父 CollectionView SelectionChangedCommand,绑定命令执行两次,对于子 CollectionView SelectionChangedCommand,绑定命令执行多次。 请检查此图片以了解目标 UI

<CollectionView 
     x:Name="SpaceListCollectionView"
     Grid.Row="1" 
     SelectionMode="Single"
     SelectedItem="{Binding SelectedSpace}"
     SelectionChangedCommand="{Binding OnSpaceClicked}"
     ItemsSource="{Binding SpaceList}">
     <CollectionView.ItemTemplate>
         <DataTemplate>
             <Grid RowDefinitions="auto,auto">
                 <Grid
                         ColumnDefinitions="*,auto" 
                         RowDefinitions="auto,auto"
                         Padding="26,10,22,0"
                         BackgroundColor="#f8f8f8"
                         Grid.Row="0">
                     <Label 
                             Grid.Row="0" 
                             Grid.Column="0"
                             Text="{Binding Space}"
                             VerticalOptions="Center"
                             FontAttributes="Bold"
                             Margin="0,0,0,10" />
                     <Image 
                             Grid.Row="0"
                             Grid.Column="1"
                             Source="{Binding ArrowImage}"
                             WidthRequest="26"
                             VerticalOptions="Center"
                             Margin="0,0,0,7" />
                     <BoxView 
                             Grid.Row="1"
                             Grid.ColumnSpan="2"
                             Color="#e7e7e7"
                             HeightRequest="1"
                             HorizontalOptions="FillAndExpand"
                             VerticalOptions="End" />
                 </Grid>
                 <CollectionView                                    
                         Grid.Row="2"
                         Grid.ColumnSpan="2" 
                         ItemsSource="{Binding Assets}"
                         SelectedItem="{Binding BindingContext.SelectedAsset, Source={x:Reference HomePage}}"
                         SelectionChangedCommand="{Binding BindingContext.OnAssetClicked, Source={x:Reference HomePage}}"
                         SelectionMode="Single"
                         IsVisible="{Binding IsExpanded}">
                     <CollectionView.ItemTemplate>
                         <DataTemplate>
                             <Grid
                                         ColumnDefinitions="auto,*,auto"
                                         BackgroundColor="White"
                                         ColumnSpacing="20"
                                         Padding="10">
                                 <Image
                                             Grid.Column="0"
                                             Source="asset_ready.png" 
                                             HeightRequest="45"/>
                                 <Grid
                                             Grid.Column="1"
                                             RowDefinitions="auto,auto,auto"
                                             VerticalOptions="Center">
                                     <Label 
                                                 Grid.Row="0"
                                                 Text="{Binding AssetType}" 
                                                 FontSize="14" 
                                                 FontAttributes="Bold"
                                             IsVisible="{Binding BindingContext.IsGroupBySpace, Source={x:Reference HomePage}}" />
                                     <Label 
                                             Grid.Row="0"
                                             Text="{Binding Space}" 
                                             FontSize="14" 
                                             IsVisible="{Binding BindingContext.IsGroupByAssetType, Source={x:Reference HomePage}}"
                                         FontAttributes="Bold" />
                                     <Label
                                                 Grid.Row="1"
                                                 Text="{Binding AssetName}"
                                                 FontSize="12" />
                                     <Label
                                                 Grid.Row="2"
                                                 Text="{Binding Barcode}"
                                                 FontSize="12" />
                                 </Grid>
                                 <Frame 
                                             Grid.Column="2"
                                             VerticalOptions="Center" 
                                     HorizontalOptions="Center"
                                             CornerRadius="50"
                                             Padding="8,3"
                                             BackgroundColor="#f0f0f0"
                                             BorderColor="Transparent">
                                     <Label 
                                                 Text="{Binding TaskCount}"
                                                 BackgroundColor="#f0f0f0"
                                         HorizontalTextAlignment="Center"/>
                                 </Frame>
                             </Grid>
                         </DataTemplate>
                     </CollectionView.ItemTemplate>
                 </CollectionView>
             </Grid>
         </DataTemplate>
     </CollectionView.ItemTemplate>
 </CollectionView>

我尝试设置

Command.CanExecute(false);
仍然执行命令。 我尝试了以下解决方案作为解决方法,但失败了。单击返回此页面将执行 OnAssetClicked 命令。

private bool _canExecute;

   public ICommand OnAssetClicked => new Command(async () =>
   {
       if (_canExecute)
       {
           _canExecute = false;
           await AssetClicked();
       }
   });

   //Bound to Appearing EventToCommandBehavior
   public ICommand OnAppearing => new Command(Initialize); 

   Private void Initialize()
   {
      _canExecute = true;
   }

  //will be called on parent collection view item selected.
  private void Expand()
  {
      try
      {
          MainThread.BeginInvokeOnMainThread(() =>
          {
              var selectedSpace = SpaceList.FirstOrDefault(x => x.Space == SelectedSpace?.Space);
              var index = SpaceList.IndexOf(selectedSpace ?? new AssetListModel());
              if (selectedSpace != null)
              {
                  selectedSpace.IsExpanded = !selectedSpace.IsExpanded;
                  if (selectedSpace.IsExpanded)
                  {
                      selectedSpace.ArrowImage = "key_up.png";
                  }
                  else
                  {
                      selectedSpace.ArrowImage = "key_down.png";
                  }
                  SpaceList[index] = selectedSpace;
              }
          });
      }
      catch (Exception ex) when (ex != null)
      {
          Debug.WriteLine(ex + " in HomePageViewModel ExpandArea");
      }
      finally
      {
          SelectedSpace = null;
      }
  }

  //will be called on child collection view item selected
  private async Task AssetClicked()
  { 
      await NavigationService.Navigate(nameof(AssetDetailsPageView));
  }

如何阻止

SelectionChangedCommand
多次执行。

c# maui .net-8.0 collectionview
1个回答
0
投票

Expand
方法中,您设置了
SpaceList[index] = selectedSpace;
,这会导致该方法执行两次。

如果您想更改

IsExpanded
属性并在运行时通知 UI,您可以为您的 Space 模型实现
INotifyPropertyChanged
接口
,如下所示。

public class SpaceModel: INotifyPropertyChanged
{
    public string Space { get; set; }

    public ObservableCollection<Asset> Assets ...

    public bool isExpanded;
    public bool IsExpanded
    {
        get
        {
            return isExpanded;

        }
        set
        {
            isExpanded = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsExpanded)));
        }
    }

    public event PropertyChangedEventHandler? PropertyChanged;
}

现在,当您更改 Space Item 的

IsExpand
属性时,它也会通知 UI 进行更改。然后您无需再次将值重置为
SpaceList
。只需删除,

SpaceList[index] = selectedSpace;

更多信息,您可以参考Viewmodels和属性更改通知INotifyPropertyChanged接口

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