#c# #xamarin #xamarin.forms
#c# #xamarin #xamarin.forms
Вопрос:
Я пытаюсь обновить существующий проект Xamarin до последних версий различных библиотек. Сами формы Xamarin находятся в общей библиотеке. На моей странице есть ListView, и я пытаюсь зафиксировать событие, вызванное, когда элемент «выбран». Однако команда ICommand в моей ViewModel не выполняется.
Примечания:
- Я использую Xamarin.Формы 4.8 … но пришлось понизить поведение.Формы до 1.3, потому что код находится в стандартной библиотеке .NET.
- Если я перейду на поведение.Формы 1.4 возникает ошибка времени разработки (см. Фото ниже)
ИНФОРМАЦИЯ ОБ ОБЩЕЙ БИБЛИОТЕКЕ:
.NET Standard 2.0
- Acr.UserDialogs Version=»7.1.0.454″
- AzureMobileClient.Версия помощников =»4.0.2.507-pre»
- Поведение.Версия Forms =»1.3.0″
- Com.Airbnb.Xamarin.Формы.Версия Лотти=»3.1.3″
- Призма.DryIoc.Версия Forms=»8.0.0.1850-pre»
- Призма.Версия Forms=»8.0.0.1850-pre»
- Refractor.MvvmHelpers Version=»1.6.2″
- Telerik.UI.for.Xamarin.Общая версия =»2020.2.624.1″
- Telerik.UI.for.Xamarin.Версия DataControls=»2020.2.624.1″
- Telerik.UI.for.Xamarin.Версия DataGrid=»2020.2.624.1″
- Telerik.UI.for.Xamarin.Версия примитивов=»2020.2.624.1″
- Версия Telerik.UI.for.Xamarin.SkiaSharp=»2020.2.624.1″
- Xamarin.Загрузка FFImageLoading.Версия Forms =»2.4.11.982″
- Xamarin.Версия FFImageLoading.Svg.Forms=»2.4.11.982″
- Xamarin.Загрузка FFImageLoading.Версия преобразований=»2.4.11.982″
- Xamarin.Версия Forms =»4.8.0.1364″
КЛАСС ПРЕОБРАЗОВАТЕЛЯ:
Исходный программист возвращает ‘ItemTapped’ EventArgs…
public class SelectedItemEventArgsConverter : IValueConverter
{
#region <Methods>
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var eventArgs = value as ItemTappedEventArgs;
return eventArgs != null ? eventArgs.Item : null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
ПРОСМОТР МОДЕЛИ:
ListView связывает и отображает элементы (см. Фото ниже)…
using CustomControls;
using Models;
using MvvmHelpers.Commands;
using Prism.Navigation;
using Prism.Services;
using System.Collections.Generic;
public class MainPageViewModel : ViewModelBase
{
#region Constructors
public MainPageViewModel(INavigationService navigationService, IPageDialogService pageDialogService, IDeviceService deviceService) : base(navigationService, pageDialogService, deviceService)
{
Initialize();
}
#endregion
#region <Properties>
public AccordionNode ShakeoutListItemsAccordion { get; private set; }
public Command<SimpleListItem> OnShakeoutListItemSelectedCommand { get; private set; }
public List<SimpleListItem> ShakeoutListItems { get; private set; } = new List<SimpleListItem>();
#endregion
#region <Events>
public async void OnShakeoutListItemSelected(SimpleListItem item)
{
if (item.Name == "Add Shakeout")
await NavigationService.NavigateAsync("ShakeoutDocumentGeneratorPage");
}
#endregion
private void Initialize()
{
// Commands
OnShakeoutListItemSelectedCommand = new Command<SimpleListItem>(OnShakeoutListItemSelected);
// Accordians
ShakeoutListItemsAccordion = new AccordionNode("OverwrittenInView", GlobalVariables.Accordion.Height, GlobalVariables.Accordion.HeaderBackgroundColor, GlobalVariables.Accordion.HeaderColorTextColor, GlobalVariables.Accordion.SeparatorColor);
// Data
ShakeoutListItems.Add(new SimpleListItem { Name = "Add Shakeout", Title = string.Empty, Type = string.Empty });
}
}
Вид:
Поскольку происходит событие ‘ItemTapped’ класса конвертера, я фокусируюсь на этом событии … но я могу изменить это (при необходимости)
<?xml version="1.0" encoding="utf-8" ?>
<views:BaseContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:behaviors="clr-namespace:Behaviors;assembly=Behaviors"
xmlns:forms="clr-namespace:FFImageLoading.Svg.Forms;assembly=FFImageLoading.Svg.Forms"
xmlns:converters="clr-namespace:ETC.Operations.Pulse.Mobile.Converters;assembly=ETC.Operations.Pulse.Mobile"
xmlns:customControls="clr-namespace:ETC.Operations.Pulse.Mobile.CustomControls;assembly=ETC.Operations.Pulse.Mobile"
xmlns:helpers="clr-namespace:ETC.Operations.Pulse.Mobile.Helpers;assembly=ETC.Operations.Pulse.Mobile"
xmlns:views="clr-namespace:ETC.Operations.Pulse.Mobile.Views;assembly=ETC.Operations.Pulse.Mobile"
x:Class="ETC.Operations.Pulse.Mobile.MainPage">
<ContentPage.Resources>
<ResourceDictionary>
<converters:SelectedItemEventArgsConverter x:Key="EventToCommand"/>
<forms:SvgImageSourceConverter x:Key="SvgImageSourceConverter"></forms:SvgImageSourceConverter>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<ScrollView VerticalOptions="FillAndExpand" Padding="10">
<StackLayout Spacing="0" Padding="0">
<!-- SHAKEOUTS -->
<StackLayout Spacing="0" Padding="0" Style="{DynamicResource AccordionTitleStyle}">
<StackLayout Style="{DynamicResource AccordionHeaderStackLayoutStyle}">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Command="{Binding ShakeoutListItemsAccordion.ExpandContractAccordion}"/>
</StackLayout.GestureRecognizers>
<Label Text="Shakeouts" Style="{DynamicResource AccordionHeaderTextStyle}" VerticalTextAlignment="Center"/>
<Label TextColor="{Binding ShakeoutListItemsAccordion.HeaderTextColor}" HorizontalOptions="EndAndExpand" Text="{Binding ShakeoutListItemsAccordion.IconText}" VerticalTextAlignment="Center"/>
</StackLayout>
<BoxView HeightRequest="1" Color="{Binding ShakeoutListItemsAccordion.LineColor}" HorizontalOptions="FillAndExpand"></BoxView>
</StackLayout>
<!-- SHAKEOUTS: Controls -->
<StackLayout BackgroundColor="{DynamicResource BackgroundColor}" HeightRequest="200" IsVisible="{Binding ShakeoutListItemsAccordion.IsExpanded}" Padding="0" Spacing="0">
<ListView
x:Name="lvShakeoutListItems"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
ItemsSource="{Binding ShakeoutListItems}"
RowHeight="40">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Style="{DynamicResource ListViewGridItemStyle}" RowSpacing="0" ColumnSpacing="0" Margin="13,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.8*" />
<ColumnDefinition Width="150" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Text="{Binding Name}" Style="{DynamicResource ListViewLabelCenterRowLeft}" TextColor="{StaticResource LabelValueTextColor}" Margin="0,10,0,0"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.Behaviors>
<behaviors:EventHandlerBehavior EventName="ItemTapped">
<behaviors:InvokeCommandAction Command="{Binding OnShakeoutListItemSelectedCommand}" Converter="{StaticResource EventToCommand}" />
</behaviors:EventHandlerBehavior>
</ListView.Behaviors>
</ListView>
</StackLayout>
</StackLayout>
</ScrollView>
</ContentPage.Content>
</views:BaseContentPage>
ИЗОБРАЖЕНИЯ ТЕЛЕФОНА:
Как вы можете видеть … ViewModel привязывается к данным.
ПРИМЕЧАНИЯ:
Обновление до поведения.Forms 1.4 генерирует ошибку времени разработки.
Обновления:
Вот мои обновления по предложениям, внесенным участниками…
- Опция «Жест касания к основному объекту ячейки» не запускает событие (вообще)
- Возникает событие «Выбранный элемент»…но не вызывает событие «MainPageViewModel OnShakeoutListItemSelected»
- В настоящее время я изучаю «Поведение Corcav» в NuGet
Комментарии:
1. Я тестирую предоставленный вами код и воспроизводю ошибку. Для поведения. В формах 1.4 сообщалось об этой проблеме, и теперь она не будет исправлена. Вы можете перейти по ссылке ниже или открыть новый выпуск на GitHub. github.com/davidbritch/behaviors/issues/22 Пожалуйста, используйте Правила поведения. Вместо этого формирует 1.3.
2. @WendyZang-MSFT Я использую поведение. Формы 1.3
Ответ №1:
Вариант 1: используйте жест касания для основного объекта ячейки
<ListView
x:Name="lvShakeoutListItems"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
ItemsSource="{Binding ShakeoutListItems}"
RowHeight="40">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Style="{DynamicResource ListViewGridItemStyle}" RowSpacing="0" ColumnSpacing="0" Margin="13,0,0,0">
**<Grid.GestureRecognizers>
<TapGestureRecognizer Command="{Binding OnShakeoutListItemSelectedCommand}" CommandParameter="{Binding .}"/>
</Grid.GestureRecognizers>**
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.8*" />
<ColumnDefinition Width="150" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Text="{Binding Name}" Style="{DynamicResource ListViewLabelCenterRowLeft}" TextColor="{StaticResource LabelValueTextColor}" Margin="0,10,0,0"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Вариант 2: использовать выбранный элемент для основного объекта ячейки
<ListView
x:Name="lvShakeoutListItems"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
ItemsSource="{Binding ShakeoutListItems}"
SelectedItem="{Binding SelctedItem}"
RowHeight="40">
...
</>
Вариант 3: используйте corcav behavior nuget, чтобы получить событие для управления поведением
Комментарии:
1. Пожалуйста, ознакомьтесь с ОБНОВЛЕНИЯМИ SECTIO0N, которые я добавил к своему вопросу (выше)
2. для варианта 1 : событие запускается (я думаю), но из-за BindingContext оно не фиксируется, попробуйте использовать in code behind . вариант 2 : он создается, у вас есть выбранный вами объект, вы можете вручную вызвать / вызвать функцию в установщике выбранного элемента