如何在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" />
这是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>
答案 0 :(得分:7)
此方法提供了一种自定义哪些项目保持突出显示的简便方法。我决定使用它,因为它让我可以完全控制突出显示的内容以及它在列表中的显示方式。 (此示例显示仅突出显示一个项目,但可以轻松扩展以突出显示更多项目。)
原始问题中的MvxListView链接到关联视图模型中的MyItems
和MyChosenItem
。 MyItems
是Item
的集合,MyChosenItem
只是一个Item
。我将isItemSelected
添加到Item
。 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");
}
}
}
注意:Item
类扩展MvxViewModel
,以便可以调用RaisePropertyChange()
。这允许my_item_layout.xaml
在该属性更改时得到通知。
从MvxListView的isItemSelected
绑定的属性更新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;
}
}
}
}
}
将UpdateItemSelections()
修改为您想要的任何选择行为非常容易。
根据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>
修改强>
最好使用MvxCommand
,而不是在设置SelectedItem
时触发突出显示的操作。似乎SelectedItem
仅在尚未选中时才设置。点击一个项目将选择它。点击另一个项目将更改选择。再次点击同一项目将不取消选中。这意味着一旦选择了某个项目,就必须保持选中一个项目。如果您需要能够取消选择列表中的所有项目,请按照原始说明进行以下修改:
向视图模型添加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();
}
更改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;
}
}
}
}
}
请务必在保存或执行对列表中所选项目执行操作的任何内容时检查MyChosenItem.isItemSelected == true
。 MyChosenItem
中可能存在未在用户看到的列表视图中选择的值。
在MvxCommand
的布局定义中将ItemClick
绑定到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; ItemClick ItemSelectedCommand"
local:MvxItemTemplate="@layout/my_item_layout" />