如何突出显示MvxListView中的选定项目

Jos*_*osh 6 android mvvmcross

如何将项目保持在MvxListView突出显示状态,直到它被取消选中或者直到选择了另一个项目为止?

我的程序有一个MvxListView正确显示项目列表.用户可以通过单击选择项目,然后单击保存按钮.存储所选项目,MyChosenItem直到保存按钮代码需要它为止.当前,所选项目在返回到未选择的颜色之前会在瞬间保持高亮显示.

这是如何MvxListView创建的:

<Mvx.MvxListView
    android:layout_width="match_parent"
    android:layout_height="260dp"
    android:layout_marginTop="40dp"
    android:id="@+id/MyMvxListViewControl"
    local:MvxBind="ItemsSource MyItems; SelectedItem MyChosenItem"
    local:MvxItemTemplate="@layout/my_item_layout" />
Run Code Online (Sandbox Code Playgroud)

这是Layout/my_item_layout.xaml:

<?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/Project.Ui.Droid"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">
    <TextView
        android:layout_width="300.0dp"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:textSize="20dp"
        android:textColor="#000000"
        local:MvxBind="Text Field1" />
    <TextView
        android:layout_width="250.0dp"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:textSize="20dp"
        android:textColor="#000000"
        local:MvxBind="Text Field2" />
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

Jos*_*osh 7

此方法提供了一种简单方法来自定义哪些项目保持突出显示 我决定使用它,因为它让我可以完全控制突出显示的内容以及它在列表中的显示方式.(此示例显示仅突出显示一个项目,但可以轻松扩展以突出显示更多项目.)

  1. 该MvxListView,在原来的问题,链接到MyItemsMyChosenItem在相关的视图模型. MyItems是一个集合Item,而且MyChosenItem只是一个单一的集合Item.我加入isItemSelectedItem.这个Item类现在看起来像这样:

    public class Item : MvxViewModel           
    {
        private string _field1;
        private string _field2;
        private bool _isItemSelected = false;
    
        public string Field1
        {
            get { return _field1; }
            set
            {
                _field1= value;
                RaisePropertyChanged("Field1");
            }
        }
    
        public string Field2
        {
            get { return _field2; }
            set
            {
                _field2= value;
                RaisePropertyChanged("Field2");
            }
        }
    
        public bool isItemSelected
        {
            get { return _isItemSelected; }
            set
            {
                _isItemSelected = value;
                RaisePropertyChanged("isItemSelected");
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    注意:Item类扩展MvxViewModel以便RaisePropertyChange()可以调用.这允许my_item_layout.xaml在该属性更改时得到通知.

  2. 更新isItemSelectedMvxListView SelectedItem绑定到的属性的每个实例.在这种情况下,这是MyChosenItem关联视图模型中的属性.这就是新代码的样子:

    public Item MyChosenItem
    {
        get { return _myChosenItem; }
        set
        {
            if (_myChosenItem != value)
            {
                _myChosenItem = value;
                UpdateItemSelections();
                RaisePropertyChanged("MyChosenItem");
            }
        }
    }
    
    // Select MyChosenItem and unselect all other items
    private void UpdateItemSelections()
    {
        if( MyItems.Count > 0)
        {
            for (int index = 0; index < MyItems.Count; index++)
            {
                // If the chosen item is the same, mark it as selected
                if (MyItems[index].Field1.Equals(MyChosenItem.Field1)
                    && MyItems[index].Field2.Equals(MyChosenItem.Field2))
                {
                    MyItems[index].isItemSelected = true;
                }
                else
                {
                    // Only trigger the property changed event if it needs to change
                    if (MyItems[index].isItemSelected)
                    {
                        MyItems[index].isItemSelected = false;
                    }
                }
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    修改UpdateItemSelections()您想要的任何选择行为将非常容易.

  3. 根据isItemSelected属性使每行执行某些操作.我只是通过控制视图的visibility属性来改变背景颜色.但是,各种各样的事情都是可能的. isItemSelected甚至可以传递给一些非常有趣的视觉效果的自定义控件.我的新人Layout/my_item_layout.xaml看起来像这样:

    <?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/Project.Ui.Droid"
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
    
        <!-- SELECTED BACKGROUND COLOR -->
        <View
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:background="#FF0000"
            local:MvxBind="Visibility isItemSelected,Converter=BoolToViewStates" />
    
        <TextView
            android:layout_width="300.0dp"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:textSize="20dp"
            android:textColor="#000000"
            local:MvxBind="Text Field1" />
        <TextView
            android:layout_width="250.0dp"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:textSize="20dp"
            android:textColor="#000000"
            local:MvxBind="Text Field2" />
    </LinearLayout>
    
    Run Code Online (Sandbox Code Playgroud)

编辑

MvxCommandSelectedItem设置时使用而不是触发突出显示的操作可能更好.似乎SelectedItem只有在尚未选择时才设置.点击一个项目将选择它.点击另一个项目将更改选择.再次点击相同的项目将不会取消选择它.这意味着一旦选择了某个项目,就必须保持选中一个项目.如果您需要能够取消选择列表中的所有项目,请按照原始说明进行以下修改:

  1. 添加MvxCommand到视图模型.调用UpdateItemSelections()MvxCommand,而不是从MyChosenItem.

    public MvxCommand ItemSelectedCommand { get; private set; }
    
    // Constructor
    public ItemSelectionViewModel()
    {
        ItemSelectedCommand = new MvxCommand(OnItemSelected);
    }
    
    public Item MyChosenItem
    {
        get { return _myChosenItem; }
        set
        {
            if (_myChosenItem != value)
            {
                _myChosenItem = value;
                //UpdateItemSelections();    // Move this to OnItemSelected()
                RaisePropertyChanged("MyChosenItem");
            }
        }
    }
    
    private void OnItemSelected()
    {
        UpdateItemSelections();
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 更改UpdateItemSelections()为切换isItemSelected属性,而不是始终将其设置为true:

    // Select MyChosenItem and unselect all other items
    private void UpdateItemSelections()
    {
        if( MyItems.Count > 0)
        {
            for (int index = 0; index < MyItems.Count; index++)
            {
                // If the chosen item is the same, mark it as selected
                if (MyItems[index].Field1.Equals(MyChosenItem.Field1)
                    && MyItems[index].Field2.Equals(MyChosenItem.Field2))
                {
                    // Toggle selected status
                    MyItems[index].isItemSelected = !MyItems[index].isItemSelected;
                }
                else
                {
                    // Only trigger the property changed event if it needs to change
                    if (MyItems[index].isItemSelected)
                    {
                        MyItems[index].isItemSelected = false;
                    }
                }
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 请记住检查MyChosenItem.isItemSelected == true何时保存或执行对列表中所选项目起作用的任何操作.可能有一个值在MyChosenItem用户看到的列表视图中未被选中.

  4. 将布局定义绑定MvxCommand到:ItemClickMvxListView

    <Mvx.MvxListView
        android:layout_width="match_parent"
        android:layout_height="260dp"
        android:layout_marginTop="40dp"
        android:id="@+id/MyMvxListViewControl"
        local:MvxBind="ItemsSource MyItems; SelectedItem MyChosenItem; ItemClick ItemSelectedCommand"
        local:MvxItemTemplate="@layout/my_item_layout" />
    
    Run Code Online (Sandbox Code Playgroud)