Xamarin Forms: TemplatedItems возвращает только ячейки просмотра из сгруппированных заголовков

Мне нужно программно получить все ячейки просмотра моего списка, чтобы я мог изменить цвет фона определенного дочернего макета в ячейке просмотра. Нет проблем с обновлением цвета для ячейки просмотра при нажатии, но мне нужно изменить цвет всех ячеек просмотра на цвет по умолчанию всякий раз, когда нажимается другая ячейка просмотра.

При поиске решения я часто находил ответы, в которых доступ к ячейкам просмотра осуществлялся через свойства времени выполнения списка (см. код ниже или второй ответ здесь: Xamarin.Forms: получить все ячейки/элементы списка.), при тестировании кода я понял, что это не работает для списков, где группировка включена.

IEnumerable<PropertyInfo> pInfos = (connectionsListView as ItemsView<Cell>).GetType().GetRuntimeProperties();
var templatedItems = pInfos.FirstOrDefault(info => info.Name == "TemplatedItems");
if (templatedItems != null)
{
  var cells = templatedItems.GetValue(connectionsListView);
    foreach (ViewCell cell in cells as Xamarin.Forms.ITemplatedItemsList<Xamarin.Forms.Cell>)
    {
        if (cell.BindingContext != null && cell.BindingContext is MyModelClass)
        {
              // Change background color of viewcell
        }
    }
}

Когда группировка включена, этот код возвращает только сгруппированные ячейки просмотра заголовка. Я не смог найти ответа, чтобы изменить этот код, поэтому вместо заголовков возвращаются фактические ячейки просмотра «тела». Есть ли какой-либо возможный способ изменить этот код, чтобы я получил ожидаемый результат, или мне нужно использовать для этого собственный рендерер?

Обновление — код xaml просмотра списка

Здесь вы можете увидеть список, который я сейчас использую в своем XAML. Я пытаюсь найти решение, в котором я могу привязать цвет фона каждой ячейки просмотра к модели (к каждому «документу» в моем случае), но на данный момент я не мог понять, как изменить цвет для каждой конкретной ячейки просмотра, когда один прослушивается. (Мне нужно изменить только цвет фона текущей выбранной ячейки просмотра, чтобы все остальные ячейки просмотра имели цвет фона по умолчанию.)

            <ListView x:Name = "DocumentListView"
                      ItemsSource = "{Binding GroupedDocuments}"
                      BackgroundColor = "WhiteSmoke"
                      HasUnevenRows = "True"
                      RefreshCommand = "{Binding LoadDocumentsCommand}"
                      IsPullToRefreshEnabled = "True"
                      Refreshing = "DocumentListView_OnRefreshing"
                      IsRefreshing = "{Binding IsBusy, Mode=OneWay}"
                      CachingStrategy = "RecycleElement"
                      IsGroupingEnabled = "True"
                      GroupDisplayBinding = "{Binding Key}"
                      GroupShortNameBinding = "{Binding Key}"
                      VerticalOptions = "StartAndExpand"
                      HorizontalOptions = "StartAndExpand"
                      Margin = "0, -20, 0, 0">
                <ListView.GroupHeaderTemplate>
                    <DataTemplate>
                        <ViewCell Height = "25">
                            <Label x:Name = "DocumentDate"
                                   FontSize = "Medium"
                                   TextColor = "#2E588C"
                                   VerticalOptions = "Center"
                                   HorizontalTextAlignment = "Center"
                                   Text = "{Binding Key}"/>
                        </ViewCell>
                    </DataTemplate>
                </ListView.GroupHeaderTemplate>
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell Height = "155" Tapped = "DocumentViewCell_OnTapped">
                            <StackLayout Padding = "10, 5, 10, 5">
                                <Frame Padding = "0" HorizontalOptions = "FillAndExpand" HasShadow = "True">
                                    <StackLayout Padding = "10" Orientation = "Horizontal" HorizontalOptions = "FillAndExpand" VerticalOptions = "StartAndExpand">
                                        <StackLayout HorizontalOptions = "StartAndExpand">
                                            <StackLayout Orientation = "Horizontal" Spacing = "15" Margin = "10, 10, 10, 0" HorizontalOptions = "StartAndExpand">
                                                <Label Text = "{Binding Name}"
                                                       LineBreakMode = "NoWrap"
                                                       FontSize = "20"
                                                       TextColor = "CornflowerBlue"
                                                       FontAttributes = "Bold"/>
                                            </StackLayout>
                                            <StackLayout Orientation = "Horizontal" Spacing = "5" Margin = "12, 0, 0, 0" HorizontalOptions = "StartAndExpand">
                                                <Label Text = "{Binding DocumentType.Name, StringFormat='Typ: {0}'}"
                                                       LineBreakMode = "NoWrap"
                                                       FontSize = "16"
                                                       TextColor = "Black"/>
                                            </StackLayout>
                                            <StackLayout Orientation = "Horizontal" Spacing = "5" Margin = "12, 3, 0, 0" HorizontalOptions = "StartAndExpand">
                                                <Label Text = "{Binding TotalValue, StringFormat='Gesamtwert: {0:F2} €'}"
                                                       LineBreakMode = "NoWrap"
                                                       FontSize = "16"
                                                       TextColor = "Black"/>
                                            </StackLayout>
                                            <StackLayout Spacing = "5" Margin = "12, 3, 0, 0" Orientation = "Horizontal" HorizontalOptions = "StartAndExpand" VerticalOptions = "Start">
                                                <Label Text = "{Binding TagCollectionString, StringFormat='Tags: {0}'}"
                                                       LineBreakMode = "WordWrap"
                                                       FontSize = "14"
                                                       TextColor = "Black" 
                                                       VerticalOptions = "CenterAndExpand"/>
                                            </StackLayout>
                                        </StackLayout>
                                        <StackLayout HorizontalOptions = "EndAndExpand" VerticalOptions = "Start" Margin = "0, 25, 25, 0">
                                            <ImageButton HeightRequest = "85" MinimumWidthRequest = "85" x:Name = "ButtonEditDocument" Source = "baseline_more_vert_black_48.png" Clicked = "ButtonEditDocument_OnClicked" Margin = "0, 0, 15, 0" BackgroundColor = "Transparent" WidthRequest = "25" />
                                        </StackLayout>
                                    </StackLayout>
                                </Frame>
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>

Обновление 2 — Использование привязок

Я придумал, как использовать привязки для сохранения текущего выбранного фона каждой ячейки просмотра в моей модели. На данный момент я столкнулся с проблемой, что пользовательский интерфейс не обновляется должным образом, когда связанные значения изменились. Вот код, который я написал до сих пор, и то, как страница обновляется при нажатии на другую ячейку просмотра:

Класс модели документа:

public class Document 
{
        public bool HasDefaultColor { get; set; }

        public string CurrentlySelectedColorFromHex
        {
            get => ColorConverter.GetHexString(CurrentlySelectedColor);
        }

        [NotMapped]
        public Color CurrentlySelectedColor => HasDefaultColor ? DefaultColor : ActivatedColor;

        private static readonly Color DefaultColor = Color.WhiteSmoke;
        private static readonly Color ActivatedColor = Color.FromHex("#2E588C");
}

Функция OnTapped в коде программной части:

        private void DocumentViewCell_OnTapped(object sender, EventArgs e)
        {                    
                    var documents = documentRepository.GetAll();
                    foreach (var document in documents)
                        document.HasDefaultColor = true;

                    selectedDocument.HasDefaultColor = false;
                    unitOfWork.Complete();
                    UpdatePage();
}

В UpdatePage() я хочу правильно обновить список после изменения связанной коллекции:

                viewModel.LoadDocuments();
                DocumentListView.BeginRefresh();

Извините, если это вопрос новичка, но я еще не нашел на него ответа или не смог понять, как правильно обновить пользовательский интерфейс, чтобы цвет фона каждой ячейки просмотра правильно обновлялся. По крайней мере, ограниченные значения сохраняются корректно при каждом вызове OnTapped().

Обновление 3 - Добавлен конвертер

Привет, ребята, я пробовал несколько вещей и застрял с обновлением связанного свойства модели. Я также пробовал триггеры данных, но не смог правильно изменить эти триггеры данных, поэтому они не работали так, как я ожидал.

До сих пор я добавлял пользовательский преобразователь bool в Color для преобразования связанного свойства:

    public class BoolToColorConverter : IValueConverter
    {
        private static readonly Color DefaultColor = Color.WhiteSmoke;
        private static readonly Color ActivatedColor = Color.FromHex("#2E588C");

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is bool activated)
                return activated ? ActivatedColor : DefaultColor;

            return DefaultColor;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is Color color)
            {
                if (color == DefaultColor)
                    return true;
            }

            return false;
        }

Преобразователь цвета возвращает правильные значения, но я не могу понять, как обновить свойство модели во время выполнения в методе OnTapped() каждой ячейки просмотра.

В настоящее время это мой метод OnTapped():

        private void DocumentViewCell_OnTapped(object sender, EventArgs e)
        {
                // Determine which document was selected
                if (sender.GetType() == typeof(ViewCell))
                {
                    ViewCell selectedViewCell = (ViewCell)sender;

                    if (selectedViewCell.BindingContext != null && selectedViewCell.BindingContext.GetType() == typeof(Document))
                    {
                        Document document = (Document)selectedViewCell.BindingContext;

                        // Update backing field selectedDocument for correct bindings and to show correct detail page
                        if (document != null)
                            selectedDocument = document;
                    }
                }

Спасибо за любую помощь заранее и спасибо всем, кто прокомментировал до сих пор.

Ты действительно, действительно не должен этого делать. Я не уверен, что кто-то может ответить на ваш вопрос, поскольку он является законным и может иметь решение, но путь, который вы выберете, в лучшем случае будет иметь много проблем.

Ivan Ičin 26.05.2019 12:07

Хорошо, я подумал, что это правильный подход, поскольку я несколько раз видел этот ответ в Интернете. Похоже, я не могу избежать написания собственного рендерера. Спасибо за Ваш ответ.

Zasam 26.05.2019 12:15

Я думаю, что вы можете/должны сделать это с привязкой данных... ViewCells иногда перерабатываются между элементами, поэтому их перечисление не кажется хорошей идеей.

Ivan Ičin 26.05.2019 12:21

Хорошо, спасибо за помощь. Я посмотрю, смогу ли я разработать решение с привязками данных.

Zasam 26.05.2019 12:29

Это довольно просто, если вы сошлетесь на свойство BackgroundColor вашего дочернего макета со ссылкой на привязку данных. Если вы хотите, я могу привести вам пример, учитывая, что вы публикуете свой XAML

Greggz 26.05.2019 12:44

Спасибо за вашу помощь, я не мог понять, как позволить всем ячейкам просмотра иметь цвет по умолчанию, когда конкретная ячейка просмотра нажимается / выбирается. Я предоставил код xaml в своем вопросе.

Zasam 26.05.2019 12:54

К сожалению, у меня нет времени, чтобы дать расширенный ответ, так что это придется сделать. По сути, вы говорите, что цвет фона зависит от выбранного элемента. Так что для меня логичным выбором было бы просто привязать его к этому, а затем использовать преобразователь значений, чтобы преобразовать его в цвет фона. Вы можете привязать другие значения к преобразователю значений, поэтому, если вы объявите его и привяжете текущий элемент, цвет по умолчанию и выбранный цвет. Все, что ему нужно сделать, это вернуть соответствующий цвет в зависимости от того, является ли входное значение тем же объектом, что и связанный элемент.

user10608418 27.05.2019 11:12

В дополнение к комментарию выше, вот ссылка, которая должна предоставить вам информацию, необходимую для настройки преобразователя значений: docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundament‌​als/…

user10608418 27.05.2019 11:13

Спасибо, @Knoop, я мог понять, как использовать конвертер для правильной привязки цвета. Я все еще застрял в том, что не знаю, как правильно обновить свойство связанной модели во время выполнения (при нажатии на ячейку просмотра). (См. мой обновленный вопрос). Я посмотрю, смогу ли я найти решение и опубликую его как ответ. Спасибо всем за то, что направили меня в правильном направлении!

Zasam 29.05.2019 21:15

если вы хотите, чтобы ваш пользовательский интерфейс обновлялся при изменении значения привязки, вы должны позволить своей модели реализовать INotifyPropertyChanged

Leo Zhu - MSFT 30.05.2019 03:01

Спасибо, @LeoZhu-MSFT за вашу помощь. Я внедрил NotifyPropteryChanged в свою модель, но застрял с правильным обновлением связанной коллекции в ViewModel. Я мог понять, как решить мою проблему, и теперь получил желаемый результат. Я опубликовал результат как ответ на этот вопрос, даже если первоначальный вопрос был немного другим. Спасибо за вашу помощь. :)

Zasam 30.05.2019 10:20
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
11
982
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

(См. ответ, который дал @Knoop, чтобы сделать это правильно с правильными привязками и командами форм xamarin)

Поскольку я смог выполнить свою первоначальную цель, которая заключалась в программном изменении цвета фона каждой ячейки просмотра в коде позади, я опубликую свой результат в качестве ответа.

Сначала я узнал, что перебирать ячейки просмотра — плохая идея, потому что это противоречит шаблону проектирования. Поэтому я использовал привязки, а также пользовательский конвертер BoolToColor для динамического обновления цвета фона ячеек просмотра.

Это код, который я написал:

Класс модели (документ):

   public class Document : BaseModel<int>, IDocument, INotifyPropertyChanged
    {
        #region INotifyPropertyChanged

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            var changed = PropertyChanged;

            changed?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion // INotifyPropertyChanged

        public bool HasDefaultColor
        {
            get => hasDefaultColor;
            set
            {
                hasDefaultColor = value;
                OnPropertyChanged();
            }
        }
    }

Преобразователь

public class BoolToColorConverter : IValueConverter (see question for detailed code...)

Реализация конвертера в xaml:

<Frame BackgroundColor = "{Binding HasDefaultColor, Converter = {converters:BoolToColorConverter}}"  Padding = "0" HorizontalOptions = "FillAndExpand" HasShadow = "True">

И, наконец (это та часть, с которой я застрял), правильное обновление коллекции в привязанной модели представления в методе OnTapped():

        private void DocumentViewCell_OnTapped(object sender, EventArgs e)
        {
            try
            {
                // Determine which document was selected
                if (sender.GetType() == typeof(ViewCell))
                {
                    ViewCell selectedViewCell = (ViewCell)sender;

                    if (selectedViewCell.BindingContext != null && selectedViewCell.BindingContext.GetType() == typeof(Document))
                    {
                        Document document = (Document)selectedViewCell.BindingContext;

                        if (document != null)
                        {
                            // Update default color (viewcell) for binded model
                            document.HasDefaultColor = !document.HasDefaultColor;

                            // Update backing field selectedDocument for correct bindings and to show correct detail page

                            ObservableCollection<Grouping<string, Document>> documents = viewModel.GroupedDocuments;
                            foreach (var group in documents)
                            {
                                foreach (var doc in group)
                                {
                                    if (doc.Name == document.Name)
                                    {
                                        doc.HasDefaultColor = document.HasDefaultColor;
                                    }
                                }
                            }

                            viewModel.GroupedDocuments = documents;
                            selectedDocument = document;
                        }
                    }
               }
           }
       }
Ответ принят как подходящий

Наконец-то у меня появилось время, чтобы подготовить для вас ответ.

Я вижу, вы уже нашли обходной путь, но поскольку он не совсем соответствует философии дизайна Xamarin.Forms (он выполняет жестко закодированную работу в коде программной части, чтобы получить то, что вы хотите, вместо использования Xamarin.Forms функциональности.

В любом случае я разработаю 2 возможных решения, которые, на мой взгляд, лучше соответствуют хорошему Xamarin.Forms дизайну.

Опция 1:

Этот параметр отслеживает текущий выбранный элемент и использует преобразователь значений для каждого элемента в списке, чтобы проверить, равен ли он этому выбранному элементу, и вернуть цвет на основе этого.

В нашем ViewModel нам нужно настроить коллекцию для нашего ListView нашего SelectedItem свойства, которое уведомляет нас об изменениях свойств, и, наконец, ItemTappedCommand, которое изменит наше SelectedItem:

private ObservableCollection<ItemGroup> _itemGroups;
public ObservableCollection<ItemGroup> ItemGroups
{
    get => _itemGroups;
    set => SetProperty(ref _itemGroups, value);
}

private Item _selectedItem;
public Item SelectedItem
{
    get => _selectedItem;
    set => SetProperty(ref _selectedItem, value);
}

private ICommand _itemTappedCommand;
public ICommand ItemTappedCommand => _itemTappedCommand ?? (_itemTappedCommand = new Command<Item>((item) =>
{
    SelectedItem = item;
}));

Затем нам понадобится ValueConverter, который проверит равенство и вернет правильное Color:

public class EqualityToColorConverter : IValueConverter
{
    public Color EqualityColor { get; set; }

    public Color InequalityColor { get; set; }
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {

        if (value == null || parameter == null)
            return InequalityColor;

        if (parameter is Binding binding && binding.Source is View view)
        {
            parameter = view.BindingContext;
        }

        return value == parameter ? EqualityColor : InequalityColor;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Этот конвертер использует небольшой обходной путь для извлечения фактического элемента из parameter, поскольку по какой-то причине он продолжал возвращать мне Binding вместо фактического Item.

Теперь, когда у нас есть все необходимое, мы можем создать нашу страницу:

<ContentPage xmlns = "http://xamarin.com/schemas/2014/forms"
             xmlns:x = "http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:converters = "clr-namespace:ColorChangeDemo.Converters"
             x:Class = "ColorChangeDemo.Views.SelectedItemPage">
    <ContentPage.Resources>
        <ResourceDictionary>
            <converters:EqualityToColorConverter x:Key = "equalityToColorConverter" EqualityColor = "Green" InequalityColor = "Gray" />
        </ResourceDictionary>
    </ContentPage.Resources>
    <ContentPage.Content>
        <ListView x:Name = "ListView"  ItemsSource = "{Binding ItemGroups}" GroupShortNameBinding = "{Binding Key}" GroupDisplayBinding = "{Binding Key}" IsGroupingEnabled = "True">
            <ListView.GroupHeaderTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Label Text = "{Binding Key}" />
                    </ViewCell>
                </DataTemplate>
            </ListView.GroupHeaderTemplate>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Button 
                            x:Name = "Button"
                            Text = "{Binding Id}" 
                            BackgroundColor = "{Binding Source = {x:Reference ListView}, Path=BindingContext.SelectedItem, Converter = {StaticResource equalityToColorConverter}, ConverterParameter = {Binding Source = {x:Reference Button}}}"
                            Command = "{Binding Source = {x:Reference ListView}, Path=BindingContext.ItemTappedCommand}"
                            CommandParameter = "{Binding .}"/>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </ContentPage.Content>
</ContentPage>

Преимущество этого решения заключается в том, что вам не нужно менять свой класс Item (если у вас нет никакого контроля над ним), однако недостатком является то, что при каждом изменении выбора все элементы будут реагировать на измененное значение. Поэтому, если отображается много элементов, это может быть неоптимальным.

Вариант 2:

Эта опция добавит свойство Selected к классу Item и будет отслеживать ранее выбранный элемент, чтобы иметь возможность отменить его выбор при выборе другого элемента.

Мы снова начинаем с нашего ViewModel, сначала с нашими свойствами:

private ObservableCollection<SelectableItemGroup> _selectableItemGroups;
public ObservableCollection<SelectableItemGroup> SelectableItemGroups
{
    get => _selectableItemGroups;
    set => SetProperty(ref _selectableItemGroups, value);
}

public ICommand ItemTappedCommand { get; }

И в конструкторе создаем нашу команду. Чтобы это работало, мы создаем локальную переменную, которую мы можем использовать для захвата в команде, чтобы мы могли отслеживать ранее выбранный элемент:

SelectableItem previous = null;

ItemTappedCommand = new Command<SelectableItem>((item) =>
{
    if (previous != null)
        previous.Selected = false;
    previous = item;
    item.Selected = true;
});

Теперь нам нужен ValueConverter, который может преобразовать наше свойство Selected в правильное Color:

public class BoolToColorConverter: IValueConverter
{
    public Color TrueColor { get; set; }

    public Color FalseColor { get; set; }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value != null && value is bool boolValue)
            return boolValue ? TrueColor : FalseColor;
        return FalseColor;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

И снова у нас есть все настройки для создания нашей страницы:

<ContentPage xmlns = "http://xamarin.com/schemas/2014/forms"
             xmlns:x = "http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:converters = "clr-namespace:ColorChangeDemo.Converters"
             x:Class = "ColorChangeDemo.Views.DeselectPage">
    <ContentPage.Resources>
        <ResourceDictionary>
            <converters:BoolToColorConverter x:Key = "boolToColorConverter" TrueColor = "Green" FalseColor = "Gray" />
        </ResourceDictionary>
    </ContentPage.Resources>
    <ContentPage.Content>
        <ListView x:Name = "ListView"  ItemsSource = "{Binding SelectableItemGroups}" GroupShortNameBinding = "{Binding Key}" GroupDisplayBinding = "{Binding Key}" IsGroupingEnabled = "True">
            <ListView.GroupHeaderTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Label Text = "{Binding Key}" />
                    </ViewCell>
                </DataTemplate>
            </ListView.GroupHeaderTemplate>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Button 
                            x:Name = "Button"
                            Text = "{Binding Id}" 
                            BackgroundColor = "{Binding Selected, Converter = {StaticResource boolToColorConverter}}"
                            Command = "{Binding Source = {x:Reference ListView}, Path=BindingContext.ItemTappedCommand}"
                            CommandParameter = "{Binding .}"/>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </ContentPage.Content>
</ContentPage>

Преимущество этой опции в том, что она не просматривает весь список, чтобы убедиться, что все правильно Color.

Демонстрационный проект

Чтобы увидеть это в действии, я загрузил небольшой демонстрационный проект, в котором я реализовал оба решения:

https://github.com/nknoop/ChangeColorDemo

Эй, @Knoop, спасибо за ваш подробный ответ и предоставленный демонстрационный проект :) Решение, которое я дал в качестве ответа, определенно не похоже на то, чтобы делать это в форме xamarin. Я реализовал второй вариант, который вы указали в своем ответе, его было легко реализовать, и он работает намного лучше, чем то, как я поступал (с обновлением всей коллекции каждый раз). Я очень ценю, что вы приложили столько усилий, чтобы ответить на мой вопрос. Наконец, я смог получить желаемый результат правильным способом (формы xamarin).

Zasam 30.05.2019 23:07

Привет, @Knoop, я обновил твой ответ как правильный ответ на этот вопрос. Спасибо за ваши усилия :)

Zasam 30.05.2019 23:12

Рад слышать, что у вас все получилось! Удачи тебе с твоим проектом:-)

user10608418 31.05.2019 02:12

Другие вопросы по теме