【问题标题】:xamarin forms: On or off the listview switch based on a condition?xamarin 表单:根据条件打开或关闭列表视图开关?
【发布时间】:2018-05-15 03:03:04
【问题描述】:

我有一个带开关的列表视图,如下图所示。

string userIds = Application.Current.Properties["GroupUserIds"].ToString();(userIds 是逗号分隔的字符串) 如果上面的字符串(userIds)中存在switch item的id,我需要打开switch item。

例如,如果 Vimal Mathew 的 id 是 120 并且 userIds 的值 = 181,481,476,120,132(120 存在于 userIds 中)。那么 Vimal Mathew 的开关应该处于 on 状态,而其他列表项开关应该处于 off 状态,那些不在 userids 字符串中。

我尝试如下:

绑定 userId 并调用转换器。

  <Switch
         Toggled="OnToggledEvent"
         IsToggled="{Binding userProfileTO.userId,  Converter={StaticResource userIdExistConverter}}"
         HorizontalOptions="EndAndExpand"
         VerticalOptions="CenterAndExpand"/>

在转换器中,通过用逗号分隔并检查 userid 是否存在于列表中,从 userIds 形成一个列表。如果 userid 存在于列表中,则返回 true,不存在则返回 false。

我的转换器代码:

class UserIdExistConverter : IValueConverter
 {
#region IValueConverter implementation
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    if (value == null)
        return string.Empty;

        bool exist = false;
        string userIds = Application.Current.Properties["GroupUserIds"].ToString();
        List<string> userIdList = userIds.Split(',').ToList();
        Debug.WriteLine("listcount:>>" + userIdList.Count);
        for (int i = 0; i < userIdList.Count; i++)
        {
            if (value.ToString() == userIdList[i])
            {
                exist = true;
                break;
            }
        }
    return exist;
}

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

但出现未处理异常:System.NotImplementedException:方法或操作未实现。

我在这里没有使用任何视图模型。我在whatsapp中做一个类似组的功能,字符串userIds包含当前组成员ID,所以当我搜索添加新成员时,已经添加的成员开关应该处于开启状态。

如果 id 在组中存在则返回 true,如果组中不存在则返回 false。

bool IsUserInList(int userId)
{
string userIds = Application.Current.Properties["GroupUserIds"].ToString();
List<int> userIdList = userIds.Split(",").Select(id => int.Parse(id)).ToList();
return userIdList.Contains(userId);
}

我不知道我的逻辑是否正确,请说明一下。

提前致谢

【问题讨论】:

  • 您尝试将您的切换绑定到可能的字符串,那么如果用户切换了开关,您的 Viewmodel(我假设您使用 mvvm)会发生什么?你的问题是,你没有像异常所说的那样实现ConvertBack...
  • 我没有使用视图模型。我在whatsapp中做一个类似组的功能,字符串userIds包含当前组成员ID,所以当我搜索添加新成员时,已经添加的成员开关应该处于开启状态。
  • 是的,但是如果您的用户现在切换其中一个开关,您的 isToggled 值绑定到一个字符串但它是一个布尔值,您认为会发生什么?!您不应该编写转换器,但可以在您的 person 类周围使用一个包装器,其中包含一个名为 IsInGroup (Bool) 的属性或其他东西,并将此值绑定到 isToggled
  • 我可以编写一个方法,根据该成员是否存在于组中返回真或假。但是如何将方法响应合并到 isToggled 属性?我添加了一个 bool 方法来提问。

标签: listview xamarin.forms


【解决方案1】:

我会完全放弃那个转换器并采用更以视图模型为中心的方式。您的页面有一个视图模型,单元格也有。与单元格关联的视图模型具有属性Selected,该属性根据用户列表中存在的值设置或取消设置。

class UsersPageViewModel : INotifyPropertyChanged
{
    public IEnumerable<UserViewModel> Users
    {
        get => this.users;

        set
        {
            if(value == this.users)
            {
                return;
            }
            this.users = value;
            OnPropertyChanged();
        }
    }

    public string UserIds 
    {
        get => this.userIds;

        set 
        {
            this.userIds = value;
            UpdateUsers();
        }
    }

    private void UpdateUsers()
    {
        var userIds = this.UserIds.Split(',').Select(s => int.Parse(s)).ToArray(); // add error handling

        foreach(var user in Users)
        {
            user.Selected = userIds.Contains(user.Id);
        }
    }

    protected void OnPropertyChanged([CallerMemberName] string callerName = null)
    {
        PropertyChanged?.Invoke(new PropertyChangedEventArgs(callerName));
    }
}

UserViewModel 非常简单

class UserViewModel : INotifyPropertyChanged
{
    User user;

    public UserViewModel(User user)
    {
        this.user = user;
    }

    public bool Selected
    {
        get => this.selected;

        set
        {
            if(selected == value)
            {
                return;
            }
            selected = value;
            OnPropertyChanged();
        }
    }

    public int Id => this.user.Id;

    // OnPropertyChanged is implemented the same way
    // add more properties as you need them
}

您的 XAML 不必关心逻辑,而只需关心如何以这种方式表示 vm。请注意,我省略了加载用户和选定用户列表的代码。我认为你可以轻松填补这个空白。

【讨论】:

  • 是的,但是您可以更好地控制使用此方法调用的时间和方法。而且您正在直接设置Selected 属性,而不是使用转换器进行转换。
  • 我告诉他不要使用转换器。我认为问题有点深,我认为他并不真正了解 IsToggled 的两种方式绑定是如何工作的......
  • @Johanned,啊,现在我明白了,我只是浏览了一下答案,还以为是他又在回答了。哦! :)
猜你喜欢
  • 2014-11-18
  • 1970-01-01
  • 1970-01-01
  • 2020-01-08
  • 2012-08-22
  • 1970-01-01
  • 2018-05-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多