2013-08-21 3 views
5

Come posso mantenere un elemento, in un MvxListView, evidenziato finché non viene deselezionato o finché non viene selezionato un altro elemento?Come evidenziare l'elemento selezionato in un MvxListView

Il mio programma ha uno MvxListView che visualizza correttamente un elenco di elementi. L'utente può selezionare un elemento, facendo clic su di esso, quindi fare clic su un pulsante Salva. L'elemento selezionato viene memorizzato in MyChosenItem finché non è necessario dal codice del pulsante di salvataggio. Attualmente, l'elemento selezionato rimane evidenziato per una frazione di secondo prima di tornare al colore non selezionato.

Questo Nasce così la 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" /> 

Questo è 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

Vuol http://stackoverflow.com/questions/5058291/highlight-listview-selected-row di aiuto? – Stuart

risposta

6

Questo metodo fornisce un modo semplice per personalizzare gli elementi rimangono evidenziati. Ho optato per questo perché mi dà il pieno controllo su ciò che è evidenziato e come viene visualizzato nella lista. (Questo esempio mostra evidenziando un solo pezzo, ma potrebbe facilmente essere esteso per evidenziare più.)

  1. Il MvxListView, nella domanda originale, collega a MyItems e MyChosenItem nel modello visualizzazione associata. MyItems è una raccolta di Item e MyChosenItem è solo una singola Item. Ho aggiunto isItemSelected a Item. La classe Item assomiglia a questo ora:

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

    Nota: La classe Item estende MvxViewModel in modo che RaisePropertyChange() può essere chiamato. Ciò consente di notificare my_item_layout.xaml quando la proprietà cambia.

  2. Aggiornare ogni istanza di isItemSelected dalla proprietà a cui si associa lo SelectedItem di MvxListView. In questo caso, questa è la proprietà MyChosenItem nel modello di vista associato. Questo è ciò che il nuovo codice è simile:

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

    Sarebbe abbastanza facile da modificare UpdateItemSelections() a qualsiasi comportamento di selezione che si desidera.

  3. Fare in modo che ogni riga faccia qualcosa in base alla proprietà isItemSelected. Ho appena modificato lo sfondo cambiando i colori controllando la proprietà di visibilità di una vista. Tuttavia, tutti i tipi di cose sono possibili. isItemSelected potrebbe anche essere passato a un controllo personalizzato per alcune immagini davvero interessanti. Il mio nuovo Layout/my_item_layout.xaml assomiglia a questo:

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

Potrebbe essere meglio utilizzare un MvxCommand invece di innescare l'azione evidenziata quando il SelectedItem è impostato. Sembra che lo SelectedItem sia impostato solo se non è già selezionato. Toccando un oggetto lo selezionerai. Toccando un altro elemento cambierà la selezione. Toccando di nuovo lo stesso oggetto sarà non deselezionarlo.Ciò significa che una volta selezionato un oggetto, un oggetto deve rimanere selezionato. Se è necessario la possibilità di deselezionare tutti gli elementi della lista, seguire queste modifiche alle istruzioni originali:

  1. Aggiungi un MvxCommand al modello di vista. Chiama UpdateItemSelections() dal MvxCommand anziché da 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. Change UpdateItemSelections() per alternare la proprietà isItemSelected invece di impostare sempre al vero:

    // 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. Ricordati di controllare MyChosenItem.isItemSelected == true durante il salvataggio o fare qualsiasi cosa che agisce sulla voce selezionata nella lista. Potrebbe esserci un valore in MyChosenItem che non è selezionato nella vista elenco che l'utente vede.

  4. Bind il MvxCommand-ItemClick nella definizione del layout del 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

Attenzione: l'ordine degli attacchi conta! Per prima cosa ho avuto l'associazione ItemClick prima che l'associazione SelectedItem, non ha funzionato. Quando ho cambiato i due (SelectedItem seguito da ItemClick) tutto ha iniziato a funzionare. – Dribbel