数据绑定不适用于 xamarin 中的列表

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

我目前正在我的 Xamarin 应用程序中使用数据绑定构建视图。但是,我遇到了一个问题,即当我修改列表的值时,列表(特别是“ChecklistSections”)不会更新。奇怪的是,当我尝试更新按钮的文本时,数据绑定工作得很好。但由于某种原因,它没有按列表的预期工作。

我正在寻找一种解决方案,以确保“ChecklistSections”列表通过数据绑定正确更新,就像按钮的文本一样。任何有关如何解决列表数据绑定问题的见解或建议将不胜感激!

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:viewModels="clr-namespace:xxx.xxx.ExternalDisplay.App.ViewModels"
             xmlns:converters="clr-namespace:xxx.xxx.ExternalDisplay.App.Converters"
             xmlns:model="clr-namespace:xxx.xxx.ExternalDisplay.Core.Models;assembly=xxx.xxx.ExternalDisplay.Core"
             x:Class="xxx.xxx.ExternalDisplay.App.Views.Checklist"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:DataType="viewModels:ChecklistViewModel"
             NavigationPage.HasNavigationBar="False"
             BackgroundColor="Black">

<ContentPage.Resources>
    <ResourceDictionary>
        <xct:InvertedBoolConverter x:Key="InvertedBoolConverter" />
        <converters:CheckedColorConverter x:Key="CheckedColorConverter" />
        <converters:InverseBooleanConverter x:Key="InverseBooleanConverter" />
        
    </ResourceDictionary>
</ContentPage.Resources>

<StackLayout Padding="10">
    <Label Text="Checklist Items" FontSize="Large" TextColor="White" HorizontalOptions="Center" VerticalOptions="StartAndExpand" Margin="0,20,0,0" />
    <Grid>
        <ListView ItemsSource="{Binding ChecklistSections}" HasUnevenRows="True"
                  HorizontalOptions="FillAndExpand"
                  VerticalOptions="FillAndExpand"
                  Margin="0,10,0,0">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="model:ChecklistSection">
                    <ViewCell>
                        <StackLayout Padding="10">
                            <!-- Add padding to the StackLayout to create free space on all sides -->
                            <Label Text="{Binding ChecklistCategory.Name}" FontAttributes="Bold" Padding="5,0,0,0" FontSize="Header" TextColor="White" />

                            <StackLayout BindableLayout.ItemsSource="{Binding ChecklistItems}">
                                <BindableLayout.ItemTemplate>
                                    <DataTemplate x:DataType="model:ChecklistItem">
                                        <StackLayout Padding="15" Orientation="Vertical" BackgroundColor="Purple">
                                            <StackLayout Orientation="Horizontal">
                                                <Label Text="{Binding ItemText}" FontSize="Large" TextColor="White" VerticalOptions="Center"/>
                                                <StackLayout HorizontalOptions="End" Orientation="Horizontal" VerticalOptions="End" >
                                                    <CheckBox IsChecked="{Binding Value}" Color="Green" WidthRequest="40" HeightRequest="40"
                                                              CheckedChanged="GreenCheckBox_CheckedChanged"   />
                                                    <CheckBox IsChecked="{Binding Value, Converter={StaticResource InverseBooleanConverter}}" Color="Red" WidthRequest="40" HeightRequest="80" MinimumHeightRequest="50"
                                                              CheckedChanged="RedCheckBox_CheckedChanged" />
                                                    <BoxView Color="{Binding Value, Converter={StaticResource CheckedColorConverter}}" 
                                                             HeightRequest="20" 
                                                             WidthRequest="20" 
                                                             VerticalOptions="Center"
                                                             HorizontalOptions="CenterAndExpand"
                                                             Margin="5,0,0,0">

                                                        <BoxView.GestureRecognizers>
                                                            <TapGestureRecognizer Tapped="BoxView_Tapped" />
                                                        </BoxView.GestureRecognizers>

                                                    </BoxView>
                                                </StackLayout>
                                            </StackLayout>
                                            <Editor  HorizontalOptions="FillAndExpand" TextColor="White"/>
                                        </StackLayout>
                                    </DataTemplate>
                                </BindableLayout.ItemTemplate>
                            </StackLayout>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
    <Button Text="{Binding ButtonText}" Command="{Binding SubmitCommand}" BackgroundColor="{StaticResource PrimaryAccentColor}" BorderRadius="10" FontAttributes="Bold" TextColor="White" HorizontalOptions="Center" VerticalOptions="EndAndExpand" Margin="0,20" />
</StackLayout>

这就是我更新清单部分的方式:

var a = ChecklistSections;

        foreach (var section in a)
        {
            var itemToUpdate = section.ChecklistItems.FirstOrDefault(item => item.Id == checklistItem.Id);
            if (itemToUpdate != null)
            {
                itemToUpdate.Value = value;

                // next two lines just for testing databinding
                ButtonText = itemToUpdate.ItemText;
                a[0].ChecklistCategory.Name = "hi hi hi";
                break; // Exit the loop after updating the item
            }
        }

        ChecklistSections = a;

清单部分:

   private ObservableCollection<ChecklistSection> _checklistSections;
        public ObservableCollection<ChecklistSection> ChecklistSections
        {
            get => _checklistSections;
            set
            {
                {
                    _checklistSections = value;
                    OnPropertyChanged(nameof(ChecklistSections));
                }
            }
        
c# asp.net xamarin xamarin.forms xamarin.android
1个回答
0
投票

如果您希望 UI 在更改绑定属性的值后自动刷新(例如

ItemText
),请重新检查您是否为您的模型实现了接口
INotifyPropertyChanged

例如:

public class YourItemModel: INotifyPropertyChanged
    {            

        private string _itemText ;
        public string ItemText 
        {
            get => _itemText;
            set
            {
                SetProperty(ref _itemText, value);
            }
        }


        bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
        {
            if (Object.Equals(storage, value))
                return false;
            storage = value;
            OnPropertyChanged(propertyName);
            return true;
        }
        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        public event PropertyChangedEventHandler PropertyChanged;

    }

注:

从文档ObservableCollection Class,我们可以发现:

ObservableCollection<T>
表示动态数据集合 当添加或删除项目时,或者当 整个列表已刷新。

所以,如果你想让UI在改变item model的值后自动刷新,使用代码是没有用的

ObservableCollection<ChecklistSection> ChecklistSections

此外,建议您直接在变量

ChecklistSections
上修改子元素属性的值,而不是使用中间变量
a

   //var a = ChecklistSections;

    foreach (var section in ChecklistSections)
    {
        //....
    }

    //ChecklistSections = a;
© www.soinside.com 2019 - 2024. All rights reserved.