Ответ 1
Обновлено 08/21: Реструктурированный ответ на бит и добавленный код очистки; Добавлено другое решение, основанное на событии с измененным свойством
Вариант 1 - Использовать настраиваемое событие
Чтобы обработать событие switch Toggled
на родительском уровне TableView
; вам нужно будет развернуть событие до родительского вида. Один из способов сделать это - разоблачить событие в пользовательском MyViewCell
.
Шаги:
-
Объявить событие в вашей пользовательской ячейке просмотра (позади кода).
public event EventHandler<SelectedItemChangedEventArgs> SelectedOrToggled;
-
Назначить
Toggled
обработчик событий для переключателя, определенного в viewcell XAML<ViewCell xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Japanese.MyViewCell"> <Grid> <Label Text = "{Binding Name}" /> <Label Text = "{Binding TotalWordCount}" /> <Switch IsToggled = "{Binding IsToggled}" Toggled="Handle_Toggled" /> </Grid>
-
И вызовите свое настраиваемое событие в нем (в коде управления)
void Handle_Toggled(object sender, Xamarin.Forms.ToggledEventArgs e) { var view = sender as BindableObject; SelectedOrToggled?.Invoke(this, new SelectedItemChangedEventArgs(view.BindingContext)); }
-
Использование. Теперь вы можете подписаться на настраиваемое событие на родительской странице, где вы используете/создаете экземпляр своего пользовательского вида.
//XAML usage //<local:MyViewCell SelectedOrToggled="selectCategoryGroup" /> protected void RefreshPage() { categoryGroups = App.DB.GetCategoryGroupWithWordCount(); var section = new TableSection("Available Categories"); foreach (var category in categoryGroups) { var cell = new MyViewCell { BindingContext = category }; // assign method as event-handler cell.SelectedOrToggled += selectCategoryGroup; section.Add(cell); } tableView.Root.Add(section); }
-
Очистка: Чтобы избежать утечек памяти, рекомендуется отказаться от подписки во время разгрузки.
protected override void OnDisappearing() { base.OnDisappearing(); foreach (var section in tableView.Root) { foreach(var cell in section) { cell.Tapped -= openCategoriesPage; } } }
Поведение выбора. Вы также можете настроить его, обработав событие Tapped
в ViewCell
и поднимите событие SelectedOrToggled
(похожее на Handle_Toggled), чтобы имитировать поведение выбора ListView
.
Вариант 2 - использовать PropertyChanged
событие в виде-модели
Вы можете прослушать изменение свойства IsToggled
в CategoryGroupWordCountVM
и соответственно отреагировать.
Шаги:
-
Использование. Вы можете подписаться на событие
PropertyChanged
в viewmodel.protected void RefreshPage() { categoryGroups = App.DB.GetCategoryGroupWithWordCount(); var section = new TableSection("Available Categories"); foreach (var category in categoryGroups) { var cell = new MyViewCell { BindingContext = category }; // assign method as event-handler cat.PropertyChanged += CategoryVM_PropertyChanged; section.Add(cell); } tableView.Root.Add(section); } async void CategoryVM_PropertyChanged(object sender, PropertyChangedEventArgs e) { if(e.PropertyName == nameof(CategoryGroupWordCountVM.IsToggled)) { var categoryGroup = (CategoryGroupWordCountVM)sender; ...//call update code here ... } }
-
Очистка: Чтобы избежать утечек памяти, рекомендуется отказаться от подписки во время разгрузки.
protected override void OnDisappearing() { base.OnDisappearing(); foreach (var section in tableView.Root) { foreach(var cell in section) { (cell as ObservableProperty)?.PropertyChanged -= CategoryVM_PropertyChanged; } } }