需要从 Xamarin 中的选取器中选择至少一项

2024-05-23

在我的应用程序中,有一个选择器和按钮。我想要两件事。

  1. 需要从选取器中选择至少一项,否则将无法单击按钮。例如就像HTML 中的必需属性

  2. 如果值为提供者1,然后导航到此页面,否则如果提供商2,然后导航至此页面。

视图中选择器和按钮的代码

<Picker x:Name="picker_provider" 
        Title="Select a Provider">
        <Picker.ItemsSource>
            <x:Array Type="{x:Type x:String}">
                <x:String>Provider 1</x:String>
                <x:String>Provider 2</x:String>
            </x:Array>
        </Picker.ItemsSource>
</Picker>

<Button
    Text="Next"
    Command="{Binding NextPageCommand}"/>

ViewModel.cs 中的按钮绑定代码

public async Task NextPage(RegisterViewModel nextpage) => await NavigationService.NavigateToAsync(nextpage, null, NavigationType.Modal);

#region Bindable Command
public ICommand NextPageCommand => new Command<RegisterViewModel>(async (nextpage) =>
    {
        await NextPage(nextpage);
    });
#endregion

您可以在按钮中使用多数据触发器来启用或禁用它,具体取决于选择器选择属性的状态。

因为您要绑定到字符串,所以您需要添加一个转换器来测试它们是 null 还是空,例如:

namespace Osma.Mobile.App.Converters
{
    public class StringNullOrEmptyValueBoolConverter: IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is string str && !string.IsNullOrEmpty(str))
            {
                // String is not null or empty
                return false;
            }
            
            // String is null or empty
            return true;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

将所需的属性添加到您的ViewModel:

public class ProviderViewModel : ABaseViewModel
{
    public ProviderViewModel(
        IUserDialogs userDialogs,
        INavigationService navigationService
        ) : base(
            nameof(ProviderViewModel),
            userDialogs,
            navigationService)
    {
    }

    public override async Task InitializeAsync(object navigationData)
    {
        await base.InitializeAsync(navigationData);
    }

   private string _selectedProvider;
   public string SelectedProvider {
       get { return _selectedProvider; }
       set 
       { 
            this.RaiseAndSetIfChanged(ref _selectedProvider, value) }
       }
  }

   private string _selectedCountry;
   public string SelectedCountry {
       get { return _selectedCountry; }
       set 
       { 
           this.RaiseAndSetIfChanged(ref _selectedCountry, value) }
       }
  }

    public async Task RegistrationPage(RegisterViewModel registration) => await NavigationService.NavigateToAsync(registration, null, NavigationType.Modal);

    public ICommand RegistrationPageCommand => new Command<RegisterViewModel>(async (registration) =>
    {
        await RegistrationPage(registration);
    }, (x) => false);
}

将转换器命名空间和资源添加到页面并实现多重触发器和绑定:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:converters="clr-namespace:Osma.Mobile.App.Converters"
             x:Class="Osma.Mobile.App.Views.ProviderPage"
             NavigationPage.HasNavigationBar="False"
             BackgroundColor="#004B86">

   <ContentPage.Resources>
    <ResourceDictionary>
        <converters:StringNullOrEmptyValueBoolConverter x:Key="stringNullOrEmptyValueBoolConverter" />
    </ResourceDictionary>
   </ContentPage.Resources>


    <ContentPage.Content>
        <StackLayout
            Spacing="30">

            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="70" />
                    <RowDefinition Height="70" />
                </Grid.RowDefinitions>
                
                <Grid Grid.Row="0">
                    <Picker 
                        x:Name="picker_country" 
                        Title="Select a Country" 
                        TextColor="Silver" 
                        TitleColor="Silver" 
                        HorizontalOptions="Start" 
                        WidthRequest = "200" 
                        VerticalOptions="Start" 
                        Margin="130,0,0,0"
                        SelectedItem="{Binding SelectedCountry}">
                        <Picker.ItemsSource>
                            <x:Array Type="{x:Type x:String}">
                                <x:String>Sweden</x:String>
                            </x:Array>
                        </Picker.ItemsSource>
                    </Picker>
                </Grid>

                <Grid Grid.Row="1">
                    <Picker 
                        x:Name="picker_provider" 
                        Title="Select a Provider" 
                        TextColor="Silver" 
                        TitleColor="Silver" 
                        HorizontalOptions="Start" 
                        WidthRequest = "200" 
                        VerticalOptions="Start" 
                        Margin="130,0,0,0"
                        SelectedItem="{Binding SelectedProvider}">
                        <Picker.ItemsSource>
                            <x:Array Type="{x:Type x:String}">
                                <x:String>Provider 1</x:String>
                            </x:Array>
                        </Picker.ItemsSource>
                    </Picker>
                </Grid>
            </Grid>

        <Button 
            BackgroundColor="#2194EF"
            TextColor="White" 
            Text="Next" 
            HeightRequest="60"
            MinimumHeightRequest="60"
            IsEnabled="False"
            Command="{Binding RegistrationPageCommand}">
            <Button.Triggers>
                <MultiTrigger TargetType="Button">
                    <MultiTrigger.Conditions>
                        <BindingCondition Binding="{Binding SelectedCountry,
                                                       Converter={StaticResource stringNullOrEmptyValueBoolConverter }}" Value="false" />
                        <BindingCondition Binding="{Binding SelectedProvider,
                                                       Converter={StaticResource stringNullOrEmptyValueBoolConverter }}" Value="false" />
                    </MultiTrigger.Conditions>
        
                    <Setter Property="IsEnabled" Value="True" />
                </MultiTrigger>
            </Button.Triggers>
        </Button>

        </StackLayout>
    </ContentPage.Content>
</ContentPage>

正如您在代码中看到的,多重触发条件是两个属性都不为 null 或为空,在这种情况下,按钮将被启用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

需要从 Xamarin 中的选取器中选择至少一项 的相关文章

  • 使用不带参数的 Split() 时,默认分隔符是什么?

    所以我看了看String Split 今天 C 中的方法 我意识到你也可以向它传递零参数 这是我从未考虑过的 使用时默认的分隔符是什么Split 没有任何参数 如果没有值 则为空白 来源自here https msdn microsoft
  • 如何将pdf页面设置设置为打印属性对话框?

    大家好 我想知道如何设置 pdf 页面设置到打印属性对话框 例如 如果我的 PDF 页面设置为横向 则布局会自动显示横向而不是纵向 如果我的 PDF 页面设置为纵向 则布局会自动显示纵向 我在这个主题上做了很多研发 但没有找到任何满意的链接
  • 返回 int& 的函数[重复]

    这个问题在这里已经有答案了 我在网上查了一下发现一篇试图解释的文章std move和右值 http thbecker net articles rvalue references section 01 html并发现了一些我实在无法掌握的东
  • 关闭 XDOCUMENT 的实例

    我收到这个错误 该进程无法访问文件 C test Person xml 因为它是 被另一个进程使用 IOException 未处理 保存文件内容后如何关闭 xml 文件的实例 using System using System Collec
  • 为什么假设 send 可能返回的数据少于在阻塞套接字上传输的请求数据?

    在流套接字上发送数据的标准方法始终是调用 send 并写入一大块数据 检查返回值以查看是否发送了所有数据 然后再次调用 send 直到整个消息被接受 例如 这是一个常见方案的简单示例 int send all int sock unsign
  • 如何在 Windows 窗体中运行屏幕保护程序作为其背景?

    如何在 Windows 窗体中运行屏幕保护程序作为其背景 用户还可以在屏幕保护程序运行时与表单控件进行交互 为什么这个 我们有一个案例 需要在用户时运行 Windows Bubbles 屏幕保护程序 可以继续与表单控件交互吗 您可以使用以下
  • 导出到 CSV 时 Gridview 出现空行

    这个问题是由进一步讨论引发的这个问题 https stackoverflow com questions 6674555 export gridview data into csv file 6674589 noredirect 1 com
  • 抽象类或接口。哪种方式是正确的?

    有两种方法可以选择抽象类或接口 微软解决方案和Oracle解决方案 微软 设计指南 请使用抽象 在 Visual Basic 中为 MustInherit 类而不是接口来将协定与实现分离 http msdn microsoft com en
  • 数据损坏 C++ 和 Python 之间的管道

    我正在编写一些代码 从 Python 获取二进制数据 将其通过管道传输到 C 对数据进行一些处理 在本例中计算互信息度量 然后将结果通过管道传输回 Python 在测试时 我发现如果我发送的数据是一组尺寸小于 1500 X 1500 的 2
  • 更改其他页面的主窗口内容

    在 WPF 应用程序的主窗口中 我有一个 Badged 元素 来自材料设计 这是我的代码
  • 有没有办法设置 log4net 内存附加程序可以包含的最大错误消息数?

    我想向根记录器添加一个内存附加程序 以便我可以连接到应用程序并获取最后 10 个事件 我只想保留最后 10 个 我担心这个附加程序会消耗太多内存 该应用程序设计为 24 7 运行 或者还有别的办法吗 您需要创建一个自定义附加程序来存储有限数
  • realloc():重新分配为 char * 上的 strcat 腾出空间时下一个大小无效 [重复]

    这个问题在这里已经有答案了 我在以下代码中收到无效内存错误 printf s n FINE 5 printf s LENGTH IS d n FINE 6 strlen buffer char realloc buffer strlen b
  • Dynamics Crm:获取状态代码/状态代码映射的元数据

    在 Dynamics CRM 2011 中 在事件实体上 状态原因 选项集 也称为状态代码 与 状态 选项集 也称为状态代码 相关 例如看这个截图 当我使用 API 检索状态原因选项集时 如下所示 RetrieveAttributeRequ
  • 将 bignum 类型结构转换为人类可读字符串的有效方法是什么?

    我有一点问题 为了增长我的 C 知识 我决定尝试实现一个基本的 bigint 库 bigint 结构的核心将是一个 32 位整数数组 选择它们是因为它们适合寄存器 这将允许我在数字之间进行操作 这些操作将在 64 位整数中溢出 这也将适合寄
  • 微软语音识别速度

    我正在使用微软的语音识别器开发一个小型练习应用程序 对于我正在做的事情来说 我似乎无法让它足够快地识别单个单词 我希望能够正常说话 系统将从我所说的内容中抓取 关键字 并生成一个字符串 目前我正在使用 5 个单词的自定义语法 红 蓝 黄 绿
  • 你能解释一下这个C++删除问题吗?

    我有以下代码 std string F WideString ws GetMyWideString std string ret StringUtils ConvertWideStringToUTF8 ws ret return ret W
  • 在 SQL Server 上执行分页的最佳方式是什么?

    我有一个数据库超过200万记录 我需要执行分页以在我的 Web 应用程序上显示 该应用程序每页必须有 10 条记录DataGrid 我已经尝试使用ROW NUMBER 但是这种方式会选择所有 200 万条记录 然后只得到 10 条记录 我也
  • 如何将 CSV 文件读入 .NET 数据表

    如何将 CSV 文件加载到System Data DataTable 根据CSV文件创建数据表 常规 ADO net 功能是否允许这样做 我一直在使用OleDb提供者 但是 如果您正在读取具有数值的行 但希望将它们视为文本 则会出现问题 但
  • 将一个 long 转换为两个 int 以进行重构

    我需要将一个参数作为两个 int 参数传递给 Telerik Report 因为它不能接受长参数 将 long 拆分为两个 int 并在不丢失数据的情况下重建它的最简单方法是什么 使用掩蔽和移位是最好的选择 根据文档 long 保证为 64
  • 将文本从文本文件添加到 PDF 文件[重复]

    这个问题在这里已经有答案了 这是我的代码 using FileStream msReport new FileStream pdfPath FileMode Create step 1 using Document pdfDoc new D

随机推荐