Domanda

Non riesco a capire bene le ragioni della proprietà di dipendenza. Perché System.Controls.TextBox & Quot; Testo & Quot; proprietà una proprietà di dipendenza e non una proprietà normale? Quali sono i vantaggi di essere una proprietà di dipendenza?

Una delle cose che sto cercando di realizzare è aggiungere una proprietà ValidationRules al mio UserControl che conterrà altre regole di convalida. Come qui:

<customControls:RequiredTextBox.ValidationRules>
                        <validators:NotNullOrEmptyValidationRule ErrorMessage="FirstName cannot be null or empty"/>
                    </customControls:RequiredTextBox.ValidationRules>

Il problema è che non sono sicuro che la proprietà ValidationRules debba essere DependencyProperty o solo una proprietà normale.

Il codice sopra riportato dà il seguente errore:

{"Cannot add element to 'ValidationRules'; the property value is null.  Error at object 'LearningWPF.ValidationRules.NotNullOrEmptyValidationRule' in markup file 'LearningWPF;component/addcustomerwindow.xaml' Line 35 Position 66."}

Ecco la proprietà ValidationRules:

 public static readonly DependencyProperty ValidationRulesProperty =
            DependencyProperty.Register("ValidationRules",
                                        typeof (Collection<ValidationRule>), typeof (RequiredTextBox),
                                        new FrameworkPropertyMetadata(null)); 

        public Collection<ValidationRule> ValidationRules
        {
            get { return (Collection<ValidationRule>)GetValue(ValidationRulesProperty); }
            set { SetValue(ValidationRulesProperty, value); }
        }
È stato utile?

Soluzione

I vantaggi sono principalmente due volte:

In primo luogo una proprietà di dipendenza viene creata solo quando viene utilizzata, ciò significa che la classe TextBox può essere molto efficiente, con un footprint di memoria ridotto poiché ha un numero minimo di proprietà reali che occupano spazio sull'heap. Ciò è particolarmente importante in WPF dove tutti i controlli sono solo raccolte di tipi sempre più specifici. Se ciascuno di quei tipi interni dichiarasse decine di proprietà per definire il comportamento e l'aspetto, allora un controllo di alto livello come un pulsante finirebbe per avere le dimensioni di una classe con qualcosa nel campo di gioco di un centinaio di proprietà.

In secondo luogo, le proprietà di dipendenza possono essere legate a un oggetto diverso dal tipo per cui sono state create. Ciò consente al caso in cui un controllo può impostare una proprietà Grid.Column, che il controllo Grid può leggere e utilizzare per il layout. Ciò significa che non abbiamo centinaia di classi di decoratori che forniscono minuscole funzionalità richieste da altri controlli. Ciò significa che xmal è molto più intuitivo e leggibile.


Modificato per rispondere all'esempio nella tua domanda rivista:

Mentre la tua proprietà di validazione non trarrà molto beneficio dall'essere una proprietà di dipendenza (sostanzialmente dai motivi di tutte le risposte finora posso solo vedere il mio commento sull'impronta della memoria che entra in gioco), e certamente non lo è è vantaggioso come nel caso della proprietà Text di una casella di testo in cui potresti voler legarlo o modificarlo in base ad altri input, lo implementerei comunque come proprietà di dipendenza. Il mio ragionamento per questo è semplice; non guadagni molto, ma non ti costa nulla - non ho mai desiderato di aver usato una proprietà di base in un controllo personalizzato mentre quando ho iniziato a scriverle, aggiornavo costantemente le mie proprietà di base in dipendenze perché volevo alcune funzionalità extra.

In parole povere, mentre la proprietà di dipendenza è più complessa per definire che una proprietà normale la utilizzerei comunque come standard di fatto per i controlli WPF, a meno che non ci siano dei buoni motivi per fare diversamente. Più o meno allo stesso modo di una proprietà è lo standard per le classi, anche se un campo è più facile da implementare.

Altri suggerimenti

I principali vantaggi che direi sono:

  1. Supporto di associazione dati di prima classe.
  2. Pulisci semantica delle proprietà associate
  3. Valori di proprietà che " dipendono " ;.

L'ultimo punto è tasto

Prima delle proprietà di dipendenza, un valore ha un valore locale, un valore animabile, un valore sostituibile, un valore modulabile, un valore modellabile richiederebbe la dichiarazione di più voci Proprietà / Campi / Dizionario, nonché stato complesso + precedenza gestione.

Le proprietà di dipendenza ti offrono tutte queste funzionalità predefinite, dichiarando solo UNA proprietà.

Detto questo, nel tuo caso, potresti non voler dichiarare le tue ValidationRules come DependencyProperty se non avrai bisogno di sfruttare queste funzionalità.

In tal caso, ti consigliamo di avere una gestione diversa per le tue raccolte (ad esempio raccolte non vuote). In questo esempio specifico, vorrei utilizzare Reflector e vedere come .NET TextBox implementa le loro raccolte di convalida e vedere se è possibile riutilizzare o copiare il codice.

Non ha senso reinventare la ruota se non sei certo che la tua ruota sarà migliore. La mia esperienza personale è che le mie ruote reinventate tendono a mancare cose;).

Come già sottolineato da Martin Harris, DependencyProperties può limitare l'impronta della memoria gettando i valori delle proprietà in un dizionario, tuttavia ciò può (e credo che sia stato fatto) da MSFT prima dell'avvento di DependencyProperties.

Martin menziona anche le proprietà associate, ma erano anche disponibili (almeno nel progettista) prima dell'avvento di DependencyProperties. L'implementazione della proprietà associata che utilizza DependencyProperties è molto più pulita.

Le proprietà di dipendenza sono necessarie se si desidera utilizzare l'associazione per popolare il valore di una proprietà. Se fosse solo una proprietà normale, non saresti in grado di associare la proprietà Text a una proprietà dell'oggetto View Model, ad esempio.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top