在xamarin中为列表中的项目进行数据绑定

nfzehxib  于 8个月前  发布在  其他
关注(0)|答案(1)|浏览(51)

有没有更有效的方法来切换复选框的值,而不必重新分配检查列表部分?正如你在代码中看到的,有两个复选框:一个是真的,另一个是假的。当用户点击true复选框时,false复选框应该自动取消选中,反之亦然。然而,我目前的实现涉及到重新分配checklistsection,导致整个视图再次呈现,我认为这不是最佳方法。
请建议一种更好的方法来处理这种情况,以提高代码的性能和效率。
有没有其他的widget我可以使用?

<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;
62o28rlo

62o28rlo1#

@Jason提出了一个很好的方法,可以帮助你实现想要的功能。即实现INotifyPropertyChanged
为了更详细,你可以考虑我下面的代码。
1.将两个CheckBox绑定到模型中的不同值:

<CheckBox IsChecked="{Binding Value1,Mode=TwoWay}" Color="Green" WidthRequest="40" HeightRequest="40"
         />
<CheckBox IsChecked="{Binding Value2,Mode=TwoWay}" Color="Red" WidthRequest="40" HeightRequest="80" MinimumHeightRequest="50"
  1. ChecklistItem模型应该实现INotifyPropertyChanged接口。这可以帮助你处理工作。每次更改第一个复选框的Value 1时,第二个复选框的Value 2也会更改。
public class ChecklistItem :INotifyPropertyChanged
{
    public string ItemText { get; set; }
    public bool value1;
    public bool value2;

    public bool Value1
    {
        get
        {
            return value1;
        }
        set
        {
            if (value1 != value) 
            {
                value1 = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Value1)));
                Value2 = !value;                                   
            }
        }
    }

    public bool Value2
    {
        get
        {
            return value2;
        }
        set
        {
            if(value2 != value)   
            {
                value2 = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Value2)));
                Value1 = !value;                
            }             
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

希望能帮上忙!

相关问题