2013-08-21 47 views
5

Làm cách nào để giữ một mục, trong một MvxListView, được đánh dấu cho đến khi nó được bỏ chọn hoặc cho đến khi một mục khác được chọn?Cách đánh dấu mục đã chọn trong một MvxListView

Chương trình của tôi có MvxListView hiển thị chính xác danh sách các mục. Người dùng có thể chọn một mục, bằng cách nhấp vào nó, và sau đó nhấp vào nút lưu. Mục đã chọn được lưu trữ trong MyChosenItem cho đến khi nó được cần bằng mã nút lưu. Hiện tại, mục đã chọn vẫn giữ nguyên phần nổi bật trong một giây sau khi quay lại màu chưa được chọn.

Đây là cách MvxListView được tạo ra:

<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" /> 

Đây là 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

Liệu http://stackoverflow.com/questions/5058291/highlight-listview-selected-row giúp? – Stuart

Trả lời

6

Phương pháp này cung cấp một cách dễ dàng tùy chỉnh các mục vẫn nhấn mạnh. Tôi đã giải quyết vấn đề này vì nó cho phép tôi kiểm soát toàn bộ nội dung được đánh dấu và cách hiển thị trong danh sách. (Ví dụ này cho thấy nổi bật chỉ có một mục, nhưng nó có thể dễ dàng được mở rộng để làm nổi bật hơn.)

  1. Các MvxListView, trong câu hỏi ban đầu, liên kết đến MyItemsMyChosenItem trong mô hình xem có liên quan. MyItems là bộ sưu tập của ItemMyChosenItem chỉ là một đơn Item. Tôi đã thêm isItemSelected vào Item. Lớp Item trông như thế này bây giờ:

    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"); 
         } 
        } 
    } 
    

    Lưu ý: Lớp Item kéo dài MvxViewModel để RaisePropertyChange() có thể được gọi. Điều này cho phép my_item_layout.xaml được thông báo khi tài sản đó thay đổi.

  2. Cập nhật từng phiên bản isItemSelected từ thuộc tính mà liên kết của của MvxListView liên kết. Trong trường hợp này, đó là thuộc tính MyChosenItem trong mô hình chế độ xem được liên kết. Đây là mã mới trông như thế nào:

    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; 
           } 
          } 
         } 
        } 
    } 
    

    Sẽ dễ dàng sửa đổi UpdateItemSelections() đối với bất kỳ hành vi lựa chọn nào bạn muốn.

  3. Làm cho mỗi hàng làm điều gì đó dựa trên thuộc tính isItemSelected. Tôi vừa tạo màu nền thay đổi bằng cách điều khiển thuộc tính hiển thị của chế độ xem. Tuy nhiên, mọi thứ đều có thể. isItemSelected thậm chí có thể được chuyển đến một điều khiển tùy chỉnh cho một số hình ảnh thực sự thú vị. mới của tôi Layout/my_item_layout.xaml trông như thế này:

    <?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> 
    

EDIT

Nó có thể là tốt hơn để sử dụng một MvxCommand thay vì kích hoạt các hành động được đánh dấu khi SelectedItem được thiết lập. Có vẻ như SelectedItem chỉ được đặt nếu nó chưa được chọn. Nhấn vào một mục sẽ chọn mục đó. Nhấn vào một mục khác sẽ thay đổi lựa chọn. Nhấn lại vào cùng một mục sẽ không bỏ chọn mục đó.Điều này có nghĩa là khi một mục được chọn, một mục phải được chọn. Nếu bạn cần khả năng bỏ chọn tất cả các mục trong danh sách, hãy thực hiện theo các sửa đổi này với hướng dẫn ban đầu:

  1. Thêm MvxCommand vào kiểu xem. Gọi UpdateItemSelections() từ số MvxCommand thay vì từ 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(); 
    } 
    
  2. Thay đổi UpdateItemSelections() để chuyển isItemSelected tài sản thay vì luôn luôn đặt nó vào đúng:

    // 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; 
           } 
          } 
         } 
        } 
    } 
    
  3. Nhớ kiểm tra MyChosenItem.isItemSelected == true khi lưu hoặc làm bất cứ điều gì tác động lên mục đã chọn trong danh sách. Có thể có một giá trị trong MyChosenItem không được chọn trong chế độ xem danh sách mà người dùng nhìn thấy.

  4. Bind các MvxCommand-ItemClick trong định nghĩa bố trí của 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" /> 
    
+1

Hãy coi chừng: thứ tự của các ràng buộc quan trọng! Đầu tiên tôi đã có ràng buộc ItemClick trước ràng buộc SelectedItem, không hoạt động. Khi tôi chuyển đổi hai (SelectedItem theo sau bởi ItemClick) tất cả bắt đầu làm việc. – Dribbel