【问题标题】:How do you use a converter to enable/disable a Xaml control in Xamarin Forms?如何使用转换器在 Xamarin Forms 中启用/禁用 Xaml 控件?
【发布时间】:2019-09-21 02:51:51
【问题描述】:

作为起点,我的测试项目是 Xamarin Forms Tab 项目 - 来自 Xamarin 模板。

我有一个转换器:

using System;
using System.Collections;
using System.Globalization;
using Xamarin.Forms;

namespace TabExample.Converters
{
    public class HaveItemsConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value != null && value is ICollection)
            {
                return ((ICollection)value).Count > 0;
            }
            return false;
        }

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

我已将其添加到 App.xaml

<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:converters="clr-namespace:TabExample.Converters"
             x:Class="TabExample.App">
    <Application.Resources>
        <ResourceDictionary>
            <!-- Converters -->
            <converters:HaveItemsConverter x:Key="HaveItemsConverter"/>

            <!--Global Styles-->
            <Color x:Key="NavigationPrimary">#2196F3</Color>
            <Style TargetType="NavigationPage">
                <Setter Property="BarBackgroundColor" Value="{StaticResource NavigationPrimary}" />
                <Setter Property="BarTextColor" Value="White" />
            </Style>
        </ResourceDictionary>
    </Application.Resources>
</Application>

我已使用转换器更新了 ItemsPage.xml 中的 ListView 以添加 IsEnabled。

        <ListView x:Name="ItemsListView" 
            ItemsSource="{Binding Items}"
            VerticalOptions="FillAndExpand"
             HasUnevenRows="true"
             RefreshCommand="{Binding LoadItemsCommand}"
             IsPullToRefreshEnabled="true"
             IsRefreshing="{Binding IsBusy, Mode=OneWay}"
             CachingStrategy="RecycleElement"
             ItemSelected="OnItemSelected"
             IsEnabled="{Binding Items, Mode=OneWay, Converter={StaticResource HaveItemsConverter}, Source={x:Reference BrowseItemsPage}}">

在 ItemsPage.xaml.cs 我添加了 ItemsProperty:

    public List<Item> Items
    {
        get { return (List<Item>)GetValue(ItemsProperty); }
        set { SetValue(ItemsProperty, value); }
    }

    public static readonly BindableProperty ItemsProperty =
        BindableProperty.Create("Items", typeof(List<Item>), typeof(ItemsPage), null, BindingMode.OneWay);

这不起作用。转换器接收空值。我需要的是转换器来使用 ItemsViewModel 中的 Items ObservableCollection:

    public ObservableCollection<Item> Items { get; set; }

如何在 Xaml 中进行属性挂钩绑定以使用 HaveItemsConverter 从 ItemsViewModel 检索列表并返回用于启用或禁用列表的布尔值?

【问题讨论】:

  • 为什么要在最后加上, Source={x:Reference BrowseItemsPage}?您似乎不需要它,因为您在上面几行直接绑定了属性 Items
  • 我不知道绑定需要什么,这就是问题所在。我真正需要的是绑定到 ViewModel 中的列表 - 在这种情况下,它是 ObservableCollection 项,而不是视图中的列表。
  • 当您删除IsEnabled 属性时,项目是否显示在ListView 中?如果是这样,{Binding Items} 工作正常,这意味着 IsEnabled="{Binding Items, Mode=OneWay, Converter={StaticResource HaveItemsConverter}}" 应该可以工作。

标签: c# xaml xamarin.forms binding viewmodel


【解决方案1】:

原因:

Source={x:Reference BrowseItemsPage}

设置 Source 时,BindingContext 会同时改变;

解决方案:

BrowseItemsPage 是什么?如果是您的 viewmodel ,则应在 contentPage 中设置 BindingContext 。否则只需使用

IsEnabled="{Binding Items, Mode=OneWay , Converter={StaticResource HaveItemsConverter}}

【讨论】:

    【解决方案2】:

    我没有获得您的代码的全部范围,这就是为什么我提供简单快速的解决方案,添加另一个属性,如 ItemsAvailable,

    bool _itemsAvailable;
    Public bool ItemsAvailable 
    {get {return _itemsAvailable;}}
    {set {_itemsAvailable=value; RaisePropert....}}
    

    并在您的 Observablecollection Set 下设置上述 bool 变量,如下所示,

    public ObservableCollection<Item> _items;
        public ObservableCollection<Item> Items
        {
            get
            {
                return _items;
            }
            set
            {
                _items = value;
                if(_items!=null && _items.Count>0)
                {
                    ItemsAvailable = true;
                }
            }
        }
    

    并为您的可见属性绑定此 ItemsAvailable 属性并删除不需要的转换器。 快乐编码:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-06
      • 1970-01-01
      相关资源
      最近更新 更多