MVX列表视图单击项目



我目前正在使用MvvmCross为Android创建一个应用程序。该应用的一部分需要一个 MvxListView,其中每个项目都有 2 个文本视图。默认情况下,其中一个文本视图处于隐藏状态。我希望实现类似手风琴的功能,单击第一个文本视图将显示/隐藏另一个文本视图。

我目前已经获得了大部分与MvvmCross可见性插件一起使用,但是单击事件绑定到MvxListView而不是其中的文本视图。我目前的工作看起来像这样:

FirstViewModel:
public class FirstViewModel
    : MvxViewModel
{
    public FirstViewModel(IListService listService)
    {
        Interests = new ObservableCollection<Interest>();
        List<Interest> tempInterests = listService.GetInterestFeeds("");
        foreach (var interest in tempInterests)
        {
            interest._parent = this;
            Interests.Add(interest);
        }
        var pluginLoader = new PluginLoader();
        pluginLoader.EnsureLoaded();
    }
    private ObservableCollection<Interest> _interests;
    public ObservableCollection<Interest> Interests
    {
        get { return _interests; }
        set { _interests = value; RaisePropertyChanged(() => Interests); }
    }
    public ICommand ItemVisibleCommand
    {
        get
        {
            return new MvxCommand<Interest>(item => item.IsVisible = !item.IsVisible);
        }
    }
}

第一视图:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    ...>
    <Mvx.MvxListView
        ...
        local:MvxBind="ItemsSource Interests"
        local:MvxItemTemplate="@layout/item_interests" />
</LinearLayout>

item_interests:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="30dp"
        local:MvxBind="Text InterestName" />
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="20dp"
        local:MvxBind="Text InterestDescription; Visibility IsVisible, Converter=Visibility" />
</LinearLayout>

为了将其绑定到 MvxListView 中的 TextView,我一直在尝试将我的代码修改为类似于如何根据 Stuart 的 anwser 在 MvxListView 中绑定 ItemClick 的内容,从而产生以下代码:

item_interest:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="30dp"
        local:MvxBind="Text InterestName; Click ItemVisibleCommand" />
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="20dp"
        local:MvxBind="Text InterestDescription; Visibility IsVisible, Converter=Visibility" />
</LinearLayout>

第一视图模型:

public class FirstViewModel
    : MvxViewModel
{
    public FirstViewModel(IListService listService)
    {
        Interests = new ObservableCollection<Interest>();
        List<Interest> tempInterests = listService.GetInterestFeeds("");
        foreach (var interest in tempInterests)
        {
            interest._parent = this;
            Interests.Add(interest);
        }
        var pluginLoader = new PluginLoader();
        pluginLoader.EnsureLoaded();
    }
    private ObservableCollection<Interest> _interests;
    public ObservableCollection<Interest> Interests
    {
        get { return _interests; }
        set { _interests = value; RaisePropertyChanged(() => Interests); }
    }
    public void MakeItemVisible(bool isVisible)
    {
        isVisible = !isVisible;
    }

利息:

public class Interest : INotifyPropertyChanged
{
    public string InterestId { get; set; }
    public string InterestName { get; set; }
    public string InterestDescription { get; set; }
    public event PropertyChangedEventHandler PropertyChanged;
    public FirstViewModel _parent { get; set; }
    private bool _isVisible;
    public bool IsVisible
    {
        get { return _isVisible; }
        set
        {
            _isVisible = value;
            onPropertyChanged(this, "IsVisible");
        }
    }
    private void onPropertyChanged(object sender, string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            PropertyChanged(sender, new PropertyChangedEventArgs(propertyName));
        }
    }

    public Interest(string id, string name, string description)
    {
        //Initialisers
    }

    private MvxCommand<bool> _itemVisible;
    public ICommand ItemVisibleCommand
    {
        get
        {
            _itemVisible = _itemVisible ?? new MvxCommand<bool>(IsVisible => _parent.MakeItemVisible(IsVisible));
            return _itemVisible;
        }
    }
}

导致以下异常:

04-04 15:05:40.575 I/MonoDroid(18011): UNHANDLED EXCEPTION: System.NullReferenceException: Object reference not set to an instance of an object
04-04 15:05:40.575 I/MonoDroid(18011): at Cirrious.MvvmCross.ViewModels.MvxCommand`1<bool>.Execute (object) <IL 0x00010, 0x00088>
04-04 15:05:40.575 I/MonoDroid(18011): at Cirrious.MvvmCross.Binding.Droid.Target.MvxViewClickBinding.ViewOnClick (object,System.EventArgs) <IL 0x0001f, 0x000fb>
04-04 15:05:40.575 I/MonoDroid(18011): at Android.Views.View/IOnClickListenerImplementor.OnClick (Android.Views.View) [0x0000d] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.12-series/a1e3982a/source/monodroid/src/Mono.Android/platforms/android-15/src/generated/Android.Views.View.cs:1615
04-04 15:05:40.575 I/MonoDroid(18011): at Android.Views.View/IOnClickListenerInvoker.n_OnClick_Landroid_view_View_ (intptr,intptr,intptr) [0x00011] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.12-series/a1e3982a/source/monodroid/src/Mono.Android/platforms/android-15/src/generated/Android.Views.View.cs:1582
04-04 15:05:40.575 I/MonoDroid(18011): at (wrapper dynamic-method) object.a963c1ac-b573-4022-b41d-f0f002438c84 (intptr,intptr,intptr) <IL 0x00017, 0x00043>
Unhandled Exception:
System.NullReferenceException: Object reference not set to an instance of an object

提前感谢任何花时间阅读所有这些:)的人


更新 - 我尝试按照斯图尔特的建议去做,并得到了以下解决方案:首先,为了保留原始的 Interest 实体,它被包装在一个 InterestWrapper 中。

public class InterestWrapper : INotifyPropertyChanged
{
    private Interest _interest;
    private InterestAndroidViewModel _parent;  //TO-DO
    public Interest Item { get { return _interest; } }
    public event PropertyChangedEventHandler PropertyChanged;
    private bool _isVisible;
    public bool IsVisible
    {
        get { return _isVisible; }
        set
        {
            _isVisible = value;
            onPropertyChanged(this, "IsVisible");
        }
    }
    private void onPropertyChanged(object sender, string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            PropertyChanged(sender, new PropertyChangedEventArgs(propertyName));
        }
    }
    public InterestWrapper(Interest interest, InterestAndroidViewModel parent)
    {
        IsVisible = false;
        _interest = interest;
        _parent = parent;
    }
    public IMvxCommand ItemVisibleCommand
    {
        get
        {
            return new MvxCommand(() => _parent.MakeItemVisible(_interest));
        }
    }
}

第一视图模型

public class FirstViewModel
    : MvxViewModel
{
    public FirstViewModel(IListService listService)
    {
        Interests = new ObservableCollection<InterestWrapper>();
        List<Interest> tempInterests = listService.GetInterestFeeds("");
        foreach (var interest in tempInterests)
        {
            InterestWrapper wrapper = new InterestWrapper(interest, this);
            Interests.Add(wrapper);
        }
    }
    private ObservableCollection<InterestWrapper> _interests;
    public ObservableCollection<InterestWrapper> Interests
    {
        get { return _interests; }
        set { _interests = value; RaisePropertyChanged(() => Interests); }
    }
    public void MakeItemVisible(Interest interest)
    {
        if (interest.IsVisible)
        {
            interest.IsVisible = !interest.IsVisible;
        }
        else
        {
            foreach (var _interest in _interests)
            {
                _interest.Item.IsVisible = false;
            }
            interest.IsVisible = !interest.IsVisible;
        }
    }
}

item_interest:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    ...
    <RelativeLayout
        ...
        <TextView
            ...
            local:MvxBind="Text Item.InterestName; Click ItemVisibleCommand" />
        <Mvx.MvxImageView
            ...
            local:MvxBind="Visibility Item.IsVisible, Converter=InvertedVisibility; Click ShowEducationsCommand" />
    </RelativeLayout>
</RelativeLayout>

local:MvxBind="Text InterestName; Click ItemVisibleCommand"只能真正调用非参数化的 MvxCommand - 它不能调用MvxCommand<bool>,因为它不知道bool值是什么。

如果需要,您可以使用CommandParameter转换器传入值 - 例如 local:MvxBind="Text InterestName; Click CommandParameter(ItemVisibleCommand, IsVisible)"

但总的来说,在这种情况下,我可能会建议将 ItemVisibleCommand 重写为"切换可见"命令

看看这个问题,它是你的问题,并有斯图尔特建议的解决方案,所以认为这就是你正在寻找的。

列表视图模板中的绑定按钮单击MvvMCross

相关内容

  • 没有找到相关文章

最新更新