繁体   English   中英

.Net Maui:如何使用单选按钮更新 Observable 集合中的单个项目?

[英].Net Maui: How can I update a single item in an Observable Collection using radio buttons?

我正在构建一个.Net maui 应用程序,我有一个问题列表,我需要使用单选按钮以轮播方式收集答案,我正在使用 MVVM 来更新用户将要获得的答案 select 但是当用户选择问题时不仅更新显示的项目的答案,而且更新集合中所有项目的答案,这是我的代码:

Model:

using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace TestMauiApp.Model
{
    public class Question:INotifyPropertyChanged
    {       

        public string Name { get; set; }

        string answer;

        public string Answer`your text`
        {
            get => answer;

            set
            {
                answer = value;
                OnPropertyChanged(nameof(Answer));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        void OnPropertyChanged([CallerMemberName] string answer = "") =>
              PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(answer));
      
    }
}

视图模型:

using CommunityToolkit.Mvvm.ComponentModel;
using System.Collections.ObjectModel;

using TestMauiApp.Model;

namespace TestMauiApp.ViewModel
{
    public partial class LightDutyViewModel : ObservableObject
    {
        public LightDutyViewModel() {
            Questions = new ObservableCollection<Question> {
                new Question { Name = "Seat Belts Condition"  },
                new Question { Name = "Horns and Siren Operation" },
                new Question { Name = "Condition of Glass/Mirrors/Adjustment" },
                new Question { Name = "Fuel Level" },
                new Question { Name = "Radio operation" }
             };
         }

        [ObservableProperty]
        ObservableCollection<Question> questions;
    }
}

Xaml:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            x:Class="TestMauiApp.LightDuty"
            xmlns:model="clr-namespace:TestMauiApp.Model"
            xmlns:viewmodel="clr-namespace:TestMauiApp.ViewModel"
            x:DataType="viewmodel:LightDutyViewModel"
            Title="Light Duty"
             BackgroundColor="#F2FCFF"
             
    <StackLayout>
        <CarouselView                 
        ItemsSource="{Binding Questions}" >
        <CarouselView.ItemTemplate>
            <DataTemplate  x:DataType="model:Question">
                <StackLayout HeightRequest="500">
                    <Frame  
                            HorizontalOptions="Center"
                            VerticalOptions="CenterAndExpand"
                         CornerRadius="5"
                       Margin="20"
                            BorderColor="Transparent"
                            BackgroundColor="#F2FCFF"                            
                            HeightRequest="400">
                            <StackLayout>
                            <Label Text="{Binding Name}"
                               FontAttributes="Bold"
                               FontSize="18"
                              HorizontalOptions="Center"
                               VerticalOptions="Center"/>

                            <StackLayout RadioButtonGroup.GroupName="questiongroup"
                                         RadioButtonGroup.SelectedValue="{Binding Answer}">
                              <RadioButton Content="OK" Value="OK" />
                              <RadioButton Content="Fail" Value="Fail" />
                            </StackLayout>                          
                                <Label Text="{Binding Answer}"
                               FontAttributes="Bold"
                               FontSize="18"
                              HorizontalOptions="Center"
                               VerticalOptions="Center" />
                            
                        </StackLayout>
                    </Frame>
                    
                </StackLayout>
            </DataTemplate>
        </CarouselView.ItemTemplate>
    </CarouselView>

    </StackLayout>
</ContentPage>

xaml.cs:

using TestMauiApp.ViewModel;
namespace TestMauiApp;

public partial class LightDuty : ContentPage
{
    public LightDuty()
    {
    InitializeComponent();   
        BindingContext = new LightDutyViewModel();
    }
}

我发现这个只更新当前答案的方法是使用下拉菜单而不是单选按钮,但他们更喜欢单选按钮,唯一的区别是 xaml 文件,如下所示:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            x:Class="TestMauiApp.LightDuty"
            xmlns:model="clr-namespace:TestMauiApp.Model"
            xmlns:viewmodel="clr-namespace:TestMauiApp.ViewModel"
            x:DataType="viewmodel:LightDutyViewModel"
            Title="Light Duty"
             BackgroundColor="#F2FCFF">
<StackLayout>
    <CarouselView                 
    ItemsSource="{Binding Questions}" >
    <CarouselView.ItemTemplate>
        <DataTemplate  x:DataType="model:Question">
            <StackLayout HeightRequest="500">
                <Frame  
                        HorizontalOptions="Center"
                        VerticalOptions="CenterAndExpand"
                     CornerRadius="5"
                   Margin="20"
                        BorderColor="Transparent"
                        BackgroundColor="#F2FCFF"                            
                        HeightRequest="400">
                        <StackLayout>
                        <Label Text="{Binding Name}"
                           FontAttributes="Bold"
                           FontSize="18"
                           HorizontalOptions="Center"
                           VerticalOptions="Center"/>

                            <Picker Title="Select Option" SelectedItem="{Binding Answer}">
                              <Picker.ItemsSource>
                                  <x:Array Type="{x:Type x:String}">
                                      <x:String>OK</x:String>
                                      <x:String>Fail</x:String>
                                  </x:Array>
                               </Picker.ItemsSource>
                             </Picker>
                      
                            <Label Text="{Binding Answer}"
                             FontAttributes="Bold"
                             FontSize="18"
                             HorizontalOptions="Center"
                             VerticalOptions="Center" />
                        
                    </StackLayout>
                </Frame>
                
            </StackLayout>
        </DataTemplate>
    </CarouselView.ItemTemplate>
</CarouselView>

</StackLayout>

对于 iOS,Github 上存在一个问题: Xamarin radio button not working properly #11659 根据hartez 评论,这是由设计引起的,似乎是一个重用问题。 即使您更改了不同的组名称,您也可能会看到单选按钮在 iOS 的 CarouselView 中表现得很奇怪。

对于 Android,它运行良好。 正如ToolmakerSteve和FreakyAli所说,为Question Model添加一个Groupname属性并绑定。

<StackLayout RadioButtonGroup.GroupName="{Binding Groupname}" ...

希望对你有帮助。

首先,我认为您应该使用复选框或开关来指示界面上的布尔值。

第二,组名应该不同,这是事实。 但我不认为绑定是您所处情况的最佳方式。

有一种处理 RadioButton 的旧方法,无需定义任何组、选定值或任何类似的东西。

没有什么能阻止您使用 ValueConverter 并为每个 RadioButton 设置 ConverterParameter。 (如果你会写IntToBoolConverter就可以了,当值为1时,第一个选中,2-第二个,以此类推)

(您也可以使用 Enums 执行此操作。因此它不必是 int。只是试图解释概念。)

我仍然在这里和那里使用它,它在 MAUI 上运行得很好。

编辑:刚刚注意到您正在使用框架,现在它们有太多问题。 如果您遇到 Borders,我建议您改用 Borders。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM