【问题标题】:Xamarin forms: Hide Flowlistview item including it's space from UI based on a string valueXamarin 表单:基于字符串值隐藏 Flowlistview 项目,包括它在 UI 中的空间
【发布时间】:2019-06-13 09:30:44
【问题描述】:

我正在使用flowlistview 来列出图像。如果pageStatus 的值为OFF,我需要隐藏图像,如果pageStatus 的值为ON,我需要显示图像。我尝试如下:

在模型中:

public string pageStatus { get; set; }
public bool pictureStatus
        {
            get
            {
                if (pageStatus == "OFF")
                    return false;
                else
                    return true;
            }
        }

在 XAML 中为图像添加了 IsVisible="{Binding pictureStatus}"。图片未显示在 UI 中,但OFF 状态图片显示空白,如下所示。

我还需要从 UI 中删除该空白区域,我该怎么做?

【问题讨论】:

  • 您在 1 中有 2 个不同的问题
  • @NickKovalsky 我只有一个问题,如何删除空格?
  • 您正在绑定到一个在更改时不会触发任何内容的属性。您需要在模型中实现 INotifyPropertyChanged,当您更改数据后调用 OnPropertyChanged("pictureStatus") 时,它将在您的绑定中更新

标签: image xamarin.forms visibility


【解决方案1】:

您可以轻松使用 IValueConverter:

XAML:

定义资源

xmlns:converter="clr-namespace:ConverterNamespace" 

   <flowlistview.Resources>
      <ResourceDictionary>
           <converter:VisibilityConverter x:Key="VisibilityConverter" />
      </ResourceDictionary>     
   </flowlistview.Resources>

绑定

IsVisible="{Binding pageStatus, Converter={StaticResource VisibilityConverter}}"

转换器类:

public class VisibilityConverter: IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {    
            if ((string)value == "ON" || (string)value != null)
                return true;
            else
                return false;    
        }

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

https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/data-binding/converters

如果您想稍后更改属性值并通知列表视图,您需要使用 INotifyPropertyChanged 如上所述。

在您的模型中:

 public class ModelClass : INotifyPropertyChanged
    {
        string _pagestatus;
        public string pageStatus
        {
            get
            {
                return _pagestatus;
            }
            set
            {
                _pagestatus = value;
                OnPropertyChanged();
            }
        }

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged([CallerMemberName] string propName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
    }
}

https://docs.microsoft.com/tr-tr/dotnet/api/system.componentmodel.inotifypropertychanged?view=netframework-4.7.2

【讨论】:

  • 我试过你的代码,关闭状态图片没有显示在列表中,但仍然有空白。
  • 我提供&lt;ContentPage.Resources&gt;而不是&lt;ContentPage.Resources&gt;
  • 你可以使用同一个转换器来处理 heightrequest
  • 对于哪些属性 heightrequest?为了形象?我们的转换器只显示 true 或 false 值,那么如何将其应用于 heightrequest?
  • HeightRequest="{Binding pageStatus, Converter={StaticResource VisibilityConverter}}" 转换器类:switch (targetType.Name) { case "Boolean": if ((string)value == "ON" | | (string)value != null) 返回真;否则返回假; case "Double": if ((string)value == "ON" || (string)value != null) 返回 30;否则返回 0;默认值:返回空; }
【解决方案2】:

您应该在绑定到列表视图的项目源之前过滤源数据。当您发现它的值为 ON 时,将其添加到您的最终项目源中。我在您的 PhotoGalleryViewModel 中修改了您的代码,例如:

HttpClient client = new HttpClient();
var Response = await client.GetAsync("REST API");
if (Response.IsSuccessStatusCode)
{
    string response = await Response.Content.ReadAsStringAsync();
    PhotoAlbum photoAlbum = new PhotoAlbum();
    List<PhotoList> dataList = new List<PhotoList>();
    if (response != "")
    {
        photoAlbum = JsonConvert.DeserializeObject<PhotoAlbum>(response.ToString());
        foreach (var photos in photoAlbum.photoList)
        {
            if (!Items.Contains(photos))
            {
                Items.Add(photos);
            }

            // Instead of using primitive data, filter it here
            if (photos.pageStatus == "ON")
            {
                dataList.Add(photos);
            }
        }

        AllItems = new ObservableCollection<PhotoList>(dataList);
        await Task.Delay(TimeSpan.FromSeconds(1));
        UserDialogs.Instance.HideLoading();
    }
    else
    {
        UserDialogs.Instance.HideLoading();
        if (Utility.IsIOSDevice())
        {
            await Application.Current.MainPage.DisplayAlert("Alert", "Something went wrong, please try again later.", "Ok");
        }
        else
        {
            ShowAlert("Something went wrong, please try again later.");
        }
    }
}
else
{
    UserDialogs.Instance.HideLoading();
    if (Utility.IsIOSDevice())
    {
        await Application.Current.MainPage.DisplayAlert("Alert", "Something went wrong at the server, please try again later.", "Ok");
    }
    else
    {
        ShowAlert("Something went wrong at the server, please try again later.");
    }
}

【讨论】:

    【解决方案3】:

    您有两个选择,要么从 ListView ItemsSource 中完全删除元素,要么在视图模型中实现 INotifyProperty 已更改,以更改每个元素的可见性。这是一个小样本。

    using System;
    using System.ComponentModel;
    using Xamarin.Forms;
    
    namespace YourNameSpace
    {
        public class YourViewModel : INotifyPropertyChanged
        {
            private string _pageStatus;
            private bool _pictureStatus;
            public event PropertyChangedEventHandler PropertyChanged;
    
            public string PageStatus
            {
                set
                {
                    if (_pageStatus != value)
                    {
                        _pageStatus = value;
                        if(_pageStatus.equals("OFF))
                        {
                            PictureStatus = false;
                        }
                        else
                        {
                            PictureStatus = true;
                        }
                        OnPropertyChanged("PageStatus");
                    }
                }
                get
                {
                    return _pageStatus;
                }
            }
    
            public bool PictureStatus
            {
                set
                {
                    if (_pictureStatus != value)
                    {
                        _pictureStatus = value;
                        OnPropertyChanged("PictureStatus");
                    }
                }
                get
                {
                    return _pictureStatus;
                }
            }
    
    
    
            protected virtual void OnPropertyChanged(string propertyName)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    

    然后,在 XAML 中

    IsVisible="{Binding PictureStatus}"
    

    【讨论】:

    • 尝试了您的建议,关闭状态图片没有显示在列表中,但空白处仍然存在。
    • 然后,正如我在回答中所说的那样,您必须从集合中删除该元素。
    猜你喜欢
    • 2019-06-05
    • 2019-10-18
    • 1970-01-01
    • 2020-04-04
    • 2019-06-12
    • 2020-04-04
    • 1970-01-01
    • 1970-01-01
    • 2020-01-23
    相关资源
    最近更新 更多