Best practice per l'associazione dei dati quando un dato non-dati è incluso nei dati

2

Sto usando .NET con Windows Form, ma credo che possano esserci problemi simili con altri toolkit.

Supponiamo di avere una lista di oggetti di un certo tipo. Usando un esempio per rendere più leggibile quanto segue, supponiamo che esista una classe Category per rappresentarli. Visualizziamo un elenco di essi per consentire a un utente di filtrare gli articoli per categoria. Associare il componente ListBox a un'origine dati di Category oggetti è un modo per farlo.

Quale sarebbe il modo migliore per aggiungere una voce denominata "Tutto" nello stesso ListBox? Supponiamo che debba essere incluso nell'elenco e non come un'opzione separata come un pulsante di opzione.

Posso pensare ai seguenti approcci, ma tutti sembrano avere uno svantaggio.

  1. Crea un'istanza di "fittizio" Category di nome "Tutto" e un ID non valido.

Questo è il modo più semplice ma si sente in modo errato concettualmente, poiché "Tutto" non è in realtà una categoria (nessun articolo appartiene a una categoria chiamata così). Inoltre, a seconda del framework, l'interfaccia utente potrebbe non essere in grado di creare oggetti Category .

  1. Non utilizzare affatto l'associazione dati; compilare la casella di riepilogo con le stringhe e utilizzare l'indice della selezione per ottenere l'oggetto dall'origine dati.

Questo può battere il punto di avere i controlli associati ai dati e aggiunge potenziali problemi: cosa succede se vogliamo anche aggiungere una voce "None" in futuro? Dovremo incrementare l'indice selezionato della casella di riepilogo di 2 anziché 1 per ottenere l'oggetto corretto dall'origine dati.

  1. Utilizza una classe intermedia, CategoryListItem , per compilare la casella di riepilogo. Ha un riferimento / puntatore a un Category che è null per le entrate fittizie.

Questo può essere più elegante, ma aggiunge il sovraccarico di creare un nuovo elenco di istanze di CategoryListItem per ogni elenco di istanze di Category che vogliamo visualizzare.

Uno dei metodi sopra riportati è consigliato per legare i dati a un componente di questo tipo o forse a un modo a cui non avevo pensato?

    
posta George T 23.09.2015 - 10:57
fonte

3 risposte

1

Normalmente, una casella di selezione a selezione singola offre un'interfaccia elenco di valori per l'impostazione e un'interfaccia a valore singolo per l'interrogazione del suo stato. Gli dai un elenco di valori da presentare e ti dice quale di questi è selezionato. (Indipendentemente dal fatto che sia sempre aperto o a discesa.) È lo stesso dei pulsanti di un gruppo di radio: solo uno dei pulsanti di opzione può contenere un punto elenco in un dato momento.

Quello che vuoi invece è un controllo che offre di nuovo un'interfaccia elenco dei valori per l'impostazione, ma un'interfaccia set-of-values per interrogare il suo stato. L'intervallo di valori possibili è di nuovo fisso, ma puoi selezionarne quanti ne vuoi, compresi nessuno di essi o tutti. Quindi, chiaramente, questo controllo è supportato da un tipo di dati Set . Il tipo di controllo che viene normalmente utilizzato per quel genere di cose è un gruppo di checkboxes o una listbox con segni di spunta o, in passato, una listbox a selezione multipla. (Questo accadeva prima che si rendessero conto che gli utenti non possono essere disturbati a tenere premuto il tasto Ctrl mentre si fa clic con il mouse.)

Ora, per qualche motivo hai deciso di utilizzare una normale casella di riepilogo per questo lavoro, il che significa che non ti interessa dare al tuo utente la possibilità di selezionare due categorie contemporaneamente, tutto ciò che vuoi siano in grado di fare è selezionare una categoria o tutte le categorie. (E forse non ci sono categorie in futuro.) Va bene, a patto che ti rendi conto che questa tua scelta dovrebbe riguardare solo l'aspetto e l'esperienza utente che il controllo offre all'utente, non dovrebbe influire sulle interfacce fornite dal controllo all'applicazione. Dal punto di vista della vostra applicazione, questo controllo dovrebbe ancora implementare un'interfaccia elenco-valori per l'impostazione e un'interfaccia set-de-valori per interrogarne il valore. La questione se conterrà una casella di controllo accanto a ciascuna scelta, o speciali voci "seleziona tutto" e "seleziona nessuno", non dovrebbe assolutamente interessare la tua applicazione. Dovrebbe essere possibile sostituirlo in futuro con un gruppo di checkbox, senza alterare il modo in cui l'applicazione interagisce con esso.

Quindi, quello che farei se fossi nei tuoi panni è che vorrei sublocare il controllo listbox esistente (o creerei un controllo completamente nuovo che aggregasse il controllo esistente, non mi ricordo in quel momento quale approccio è raccomandato in WinForms,) per creare un nuovo controllo a selezione multipla che assomiglia ad un elenco, ma offre un'interfaccia set-of-value per interrogarne il valore.

Vorrei che il nuovo controllo aggiungesse a se stesso uno o due pseudo-elementi aggiuntivi necessari per poter facilmente selezionare tutto il suo contenuto o nessuno dei suoi contenuti. Ciò corrisponderebbe più strettamente all'opzione 1 qui sopra, ma è irrilevante, perché questo approccio è molto più che l'opzione n. 1. Nota come, quando descrivi questo controllo, stiamo parlando di "items" e non di "categorie": questo è un controllo general purpose che può essere usato per qualsiasi cosa tu possa pensare oltre alle categorie: riutilizzabile, e anche sostituibile con qualcosa di meglio se il bisogno sorge in futuro.

Il punto dietro la mia raccomandazione è di evitare di rovinare la tua logica applicativa con considerazioni di interazione utente a grana fine. Mantenere le cose separate e lasciare che l'esperienza dell'utente sia l'unica responsabilità dei controlli della GUI stessi. Lascia che sia il loro problema. I controlli della GUI dovrebbero astrarre il modo in cui funzionano dietro interfacce semplici, pulite e minimaliste che corrispondono a semplici tipi di dati astratti e la logica dell'applicazione dovrebbe solo interagire con queste interfacce di tipo di dati astratti.

    
risposta data 23.09.2015 - 14:52
fonte
0

Sembra che tu stia confondendo il concetto di modello di business con un modello di vista. Se la classe Category viene utilizzata come modello aziendale, una voce "Tutto" non ha senso. Tuttavia, se stai collegando i dati direttamente all'interfaccia utente, allora quello che hai è in realtà un modello di visualizzazione. Una voce "Tutto" ha perfettamente senso qui, perché un modello di vista modella semplicemente i dati che vuoi ottenere sullo schermo, indipendentemente da quale potrebbe essere.

Le tue opzioni 1, 2 e 3 sono tutti tentativi di fare una distinzione tra questi due tipi di modello. Per quanto riguarda il migliore da scegliere, beh, questo dipende da come si desidera progettare il resto della propria applicazione. Personalmente, lo renderei esplicito e ho due classi, ad es.

  • Models.Category - i dati aziendali sottostanti
  • ViewModels.Category : i dati aziendali più una linea "Tutti"

Il tuo codice di presentazione è quindi responsabile della traduzione reciproca tra le due classi. Il tuo codice di visualizzazione conosce solo ViewModels.Category e il tuo codice repository / back-end conosce solo Models.Category .

    
risposta data 23.09.2015 - 15:04
fonte
0

Non associare i tuoi oggetti direttamente a ListBox (suppongo che lo hai fatto aggiungendo ogni oggetto di categoria separatamente, perché non conosco alcun modo per impostare la proprietà DataSource su un elenco di oggetti).

Il mio suggerimento:
Crea un Enum EnumCategory, che contiene i valori di tutte le possibili categorie, inclusi "all" e "none" e qualsiasi cosa tu voglia. Collega questo Enum come DataSource al ListBox (funziona anche per una casella combinata).
Con questo puoi migliorare Enum quando vuoi senza problemi.

Se hai bisogno anche di nomi comodi (compresi spazi e altri caratteri che non appartengono ai nomi delle variabili) o supporto multilingua, fammi sapere. Entrambi possono essere aggiunti facilmente.

    
risposta data 24.09.2015 - 19:25
fonte

Leggi altre domande sui tag