CollectionView SelectionChange事件在Android中无法正常工作(.NET MAUI)
我正在尝试在.NET MAUI中创建自定义标签控件,为此,我首先尝试使用ScrollView和BindableStackLayout控件尝试过它,但是在此,我面临问题。
这里报告 solollview bug
,作为另一种方法或工作,我试图使用CollectionView开发相同的选项卡控制。
这种替代方法在iOS中工作正常,但在Android中无法正常工作。
在Android和iOS中都有一个问题。我将BoxView Control作为所选选项卡的指示器。我将仅显示选定的选项卡,但这仅在第一个选项卡中显示,当我单击其他选项卡时,该选项卡会更改,但不会从第一个选项卡中隐藏并在其他选定的选项卡中可见。
我已经为选定状态使用了带有白色的Visual State Manager,因为它看起来像是我尝试使用BoxView创建的指示器。但这也显示仅当该视图获得iOS加载时,我必须先选择选项卡,然后仅在其中显示所选颜色。
这是我所做的:
mainpage.xaml
<ContentPage.Content>
<Grid RowDefinitions="50, *" RowSpacing="0">
<CollectionView x:Name="TabsView"
Grid.Row="0"
ItemsSource="{Binding Tabs,Mode=TwoWay}"
ItemsUpdatingScrollMode="KeepItemsInView"
ItemSizingStrategy="MeasureAllItems"
SelectedItem="{Binding SelectedTab}"
SelectionChangedCommand="{Binding Path=BindingContext.TabChangedCommand,Source={x:Reference TabsView}}"
SelectionChangedCommandParameter="{Binding SelectedTab}"
SelectionMode="Single">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal"/>
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid RowSpacing="0" RowDefinitions="*, 3">
<Label Grid.Row="0"
Text="{Binding TabTitle}"
TextColor="White"
BackgroundColor="navy"
Padding="20,0"
VerticalTextAlignment="Center"
HorizontalTextAlignment="Center"
FontSize="12" />
<BoxView Grid.Row="1" Color="{Binding BoxColor}"
IsVisible="{Binding IsSelected}"/>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal"/>
<VisualState Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="White" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<tabs:ParentRecordTabView Grid.Row="1"
IsVisible="{Binding IsParentRecordTabVisible}"
VerticalOptions="FillAndExpand"/>
<tabs:AdditionalInfoTabView Grid.Row="1"
IsVisible="{Binding IsAdditionalInfoTabVisible}"
VerticalOptions="FillAndExpand" />
</Grid>
</ContentPage.Content>
mainpageViewModel.cs
public class MainPageViewModel : BaseViewModel
{
public MainPageViewModel()
{
GetTabs();
}
private bool _isParentRecordTabVisible = true;
private bool _isAdditionalInfoTabVisible;
private ObservableCollection<TabViewModel> _tabs { get; set; }
private TabViewModel _selectedTab { get; set; }
public bool IsParentRecordTabVisible
{
get => _isParentRecordTabVisible;
set { _isParentRecordTabVisible = value; OnPropertyChanged(nameof(IsParentRecordTabVisible)); }
}
public bool IsAdditionalInfoTabVisible
{
get => _isAdditionalInfoTabVisible;
set { _isAdditionalInfoTabVisible = value; OnPropertyChanged(nameof(IsAdditionalInfoTabVisible)); }
}
public ObservableCollection<TabViewModel> Tabs
{
get => _tabs;
set { _tabs = value; OnPropertyChanged(nameof(Tabs)); }
}
public TabViewModel SelectedTab
{
get => _selectedTab;
set
{
_selectedTab = value;
OnPropertyChanged(nameof(SelectedTab));
}
}
public ICommand TabChangedCommand { get { return new Command<TabViewModel>(ChangeTabClick); } }
private void GetTabs()
{
Tabs = new ObservableCollection<TabViewModel>();
Tabs.Add(new TabViewModel { TabId = 1, IsSelected = true, TabTitle = "Parent record" });
Tabs.Add(new TabViewModel { TabId = 2, TabTitle = "Additional Info" });
Tabs.Add(new TabViewModel { TabId = 3, TabTitle = "Contacts" });
Tabs.Add(new TabViewModel { TabId = 4, TabTitle = "Previous inspections" });
Tabs.Add(new TabViewModel { TabId = 5, TabTitle = "Attachments" });
SelectedTab = Tabs.FirstOrDefault();
}
public void ChangeTabClick(TabViewModel tab)
{
Tabs.All((arg) =>
{
if (arg.TabId == tab.TabId)
{
arg.IsSelected = true;
}
else
{
arg.IsSelected = false;
}
return true;
});
SelectedTab = Tabs.Where(t => t.IsSelected == true).FirstOrDefault();
switch (SelectedTab.TabId)
{
case 1:
IsParentRecordTabVisible = true;
IsAdditionalInfoTabVisible = false;
break;
case 2:
IsParentRecordTabVisible = false;
IsAdditionalInfoTabVisible = true;
break;
}
}
}
tabviewmodel.cs
public class TabViewModel : BaseViewModel
{
private bool _IsSelected;
public bool IsSelected
{
get { return _IsSelected; }
set
{
_IsSelected = value;
OnPropertyChanged(nameof(IsSelected));
}
}
private int _TabId;
public int TabId
{
get { return _TabId; }
set
{
_TabId = value;
OnPropertyChanged(nameof(TabId));
}
}
private string _TabTitle;
public string TabTitle
{
get { return _TabTitle; }
set
{
_TabTitle = value;
OnPropertyChanged(nameof(TabTitle));
}
}
}
注意:这种相同的方法在xamarin.forms.forms(Visual Studio 2019)中再次正常工作,这只是在MAUI中不起作用,所以有人注意到类似这样的东西吗?
如何重现错误:检查github
I'm trying to create custom tabs control in .Net MAUI, for that, I had first tried it with ScrollView and BindableStackLayout control but in that, I'm facing a problem.
Reported here Custom tabs with ScrollView bug
So, as an alternative approach or work-around, I have tried to develop the same Tabs control using CollectionView.
This alternative approach is working fine in iOS but not working properly in Android.
There is one problem that is common in both Android and iOS. I have taken BoxView control as an Indicator for the selected tab. That I'm going to show only for the Selected tab but this just shows in the first tab, when I click on other tabs the tabs get changed but it does not get hidden from the first tab and get visible in the other selected tab.
I have used the visual state manager with white color for the selected state because it gives looks like an indicator which I',m trying to create using BoxView. But this also shows Selected item for Android only when that view gets loads for iOS I have to select the tab first then only it shows the selected color there.
Here is what I have done:
MainPage.xaml
<ContentPage.Content>
<Grid RowDefinitions="50, *" RowSpacing="0">
<CollectionView x:Name="TabsView"
Grid.Row="0"
ItemsSource="{Binding Tabs,Mode=TwoWay}"
ItemsUpdatingScrollMode="KeepItemsInView"
ItemSizingStrategy="MeasureAllItems"
SelectedItem="{Binding SelectedTab}"
SelectionChangedCommand="{Binding Path=BindingContext.TabChangedCommand,Source={x:Reference TabsView}}"
SelectionChangedCommandParameter="{Binding SelectedTab}"
SelectionMode="Single">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal"/>
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid RowSpacing="0" RowDefinitions="*, 3">
<Label Grid.Row="0"
Text="{Binding TabTitle}"
TextColor="White"
BackgroundColor="navy"
Padding="20,0"
VerticalTextAlignment="Center"
HorizontalTextAlignment="Center"
FontSize="12" />
<BoxView Grid.Row="1" Color="{Binding BoxColor}"
IsVisible="{Binding IsSelected}"/>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal"/>
<VisualState Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="White" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<tabs:ParentRecordTabView Grid.Row="1"
IsVisible="{Binding IsParentRecordTabVisible}"
VerticalOptions="FillAndExpand"/>
<tabs:AdditionalInfoTabView Grid.Row="1"
IsVisible="{Binding IsAdditionalInfoTabVisible}"
VerticalOptions="FillAndExpand" />
</Grid>
</ContentPage.Content>
MainPageViewModel.cs
public class MainPageViewModel : BaseViewModel
{
public MainPageViewModel()
{
GetTabs();
}
private bool _isParentRecordTabVisible = true;
private bool _isAdditionalInfoTabVisible;
private ObservableCollection<TabViewModel> _tabs { get; set; }
private TabViewModel _selectedTab { get; set; }
public bool IsParentRecordTabVisible
{
get => _isParentRecordTabVisible;
set { _isParentRecordTabVisible = value; OnPropertyChanged(nameof(IsParentRecordTabVisible)); }
}
public bool IsAdditionalInfoTabVisible
{
get => _isAdditionalInfoTabVisible;
set { _isAdditionalInfoTabVisible = value; OnPropertyChanged(nameof(IsAdditionalInfoTabVisible)); }
}
public ObservableCollection<TabViewModel> Tabs
{
get => _tabs;
set { _tabs = value; OnPropertyChanged(nameof(Tabs)); }
}
public TabViewModel SelectedTab
{
get => _selectedTab;
set
{
_selectedTab = value;
OnPropertyChanged(nameof(SelectedTab));
}
}
public ICommand TabChangedCommand { get { return new Command<TabViewModel>(ChangeTabClick); } }
private void GetTabs()
{
Tabs = new ObservableCollection<TabViewModel>();
Tabs.Add(new TabViewModel { TabId = 1, IsSelected = true, TabTitle = "Parent record" });
Tabs.Add(new TabViewModel { TabId = 2, TabTitle = "Additional Info" });
Tabs.Add(new TabViewModel { TabId = 3, TabTitle = "Contacts" });
Tabs.Add(new TabViewModel { TabId = 4, TabTitle = "Previous inspections" });
Tabs.Add(new TabViewModel { TabId = 5, TabTitle = "Attachments" });
SelectedTab = Tabs.FirstOrDefault();
}
public void ChangeTabClick(TabViewModel tab)
{
Tabs.All((arg) =>
{
if (arg.TabId == tab.TabId)
{
arg.IsSelected = true;
}
else
{
arg.IsSelected = false;
}
return true;
});
SelectedTab = Tabs.Where(t => t.IsSelected == true).FirstOrDefault();
switch (SelectedTab.TabId)
{
case 1:
IsParentRecordTabVisible = true;
IsAdditionalInfoTabVisible = false;
break;
case 2:
IsParentRecordTabVisible = false;
IsAdditionalInfoTabVisible = true;
break;
}
}
}
TabViewModel.cs
public class TabViewModel : BaseViewModel
{
private bool _IsSelected;
public bool IsSelected
{
get { return _IsSelected; }
set
{
_IsSelected = value;
OnPropertyChanged(nameof(IsSelected));
}
}
private int _TabId;
public int TabId
{
get { return _TabId; }
set
{
_TabId = value;
OnPropertyChanged(nameof(TabId));
}
}
private string _TabTitle;
public string TabTitle
{
get { return _TabTitle; }
set
{
_TabTitle = value;
OnPropertyChanged(nameof(TabTitle));
}
}
}
Note: This same approach again works fine in Xamarin.Forms (Visual Studio 2019), this just not working in MAUI, so does anyone notice something like this?
How to Reproduce error: check github
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
删除项目中的BoxView默认样式。资源&gt;样式&gt; styles.xml
您可以使用
iSVisible
属性显示boxview
是否而不是用boxColor
绑定颜色。删除selectionChangedCommand
,selectionChangedCommandParameter
和VisualStateManager.VisalStateGroups
inCollection> Collection> Collection view
以及。>
设置
selectedtab
属性如下。Remove the BoxView default style in your project. Resource> Styles> Styles.xml
You could use the
IsVisible
property to show theBoxView
or not instead of binding color withBoxColor
. Remove theSelectionChangedCommand
,SelectionChangedCommandParameter
andVisualStateManager.VisualStateGroups
inCollectionView
as well.Set the
SelectedTab
property like below.