Redigeringsdialoger och deskriptorer

Objektmodellering och databaslagringen är enkelt med Dynamix. Detta behandlas i detalj i andra artiklar, men i princip räcker det att definiera objektegenskaper och låta Dynamix sköta lagring, cachning och typkontroll.

Exempel på ett objekt som hanterar frågor och svar, med en tillhörande bild:

  1. C#
  1. [Serializable]
  2. public class QuestionAndAnswer : Dynamix.Object
  3. {
  4. public static readonly TextProperty p_Question =
  5. new TextProperty( "Question" );
  6. public static readonly TextProperty p_Answer =
  7. new TextProperty( "Answer" );
  8. public static readonly ObjectProperty p_Image =
  9. new ObjectProperty( "Image", typeof( Dynamix.Image ),
  10. ObjectPropertyFlags.Cascaded );
  11. public QuestionAndAnswer() {}
  12. protected QuestionAndAnswer( ObjectID id ) : base( id ) {}
  13. protected QuestionAndAnswer( SerializationInfo info,
  14. StreamingContext context )
  15. : base( info, context ) {}
  16. public string Question
  17. {
  18. get { return GetPropertyValue( p_Question ); }
  19. set { SetPropertyValue( p_Question, value ); }
  20. }
  21. public string Answer
  22. {
  23. get { return GetPropertyValue( p_Answer ); }
  24. set { SetPropertyValue( p_Answer, value ); }
  25. }
  26. public Dynamix.Image Image
  27. {
  28. get { return (Dynamix.Image)GetPropertyValue( p_Image ); }
  29. set { SetPropertyValue( p_Image, value ); }
  30. }
  31. }

För att redigera ett enstaka objekt skapas normalt en gränssnittsdialog som visar objektets egenskaper och låter redaktören ändra dem.

Standardkontroller

Det mest rättframma men också mest tidskrävande och omständliga sättet är att:

  • Lägg in en etikett (Label) och en redigerarkontroll, t ex textboxar eller bildväljare för varje egenskap med hjälp av visual studio:s designer

  • Koppla ihop etiketterna med kontrollerna t ex med hjälp av egenskapen AssociatedControlID

  • Ladda värden i kontrollerna vid t ex PageLoad

  • Spara värden när dialogens ok-knapp trycks

Egenskapsredigerare

Ett lite smidigare sätt är att använda Dynamix generella kontroll för egenskapsredigering: GeneralPropertyEditor. När denna kontroll läggs in i formuläret ser den ut enligt:

 

GeneralPropertyEditor

Ännu så länge vet inte kontrollen vad den förväntas redigera. Nästa steg är att knyta den till en objektegenskap med attributet PropertyName. Egenskapen ska finnas i en klass som anges i egenskapen DesignerObjectType.

Egenskaper för GeneralPropertyEditor-kontrollen

När en egenskap och objekttyp, i det här fallet egenskapen Question i TestSite.QuestionAndAnswer har pekats ut ändrar redigerarkontrollen utseende till:

GeneralPropertyEditor knuten till egenskapen Question

Redigerarkontrollen har fått etiketten [Question], dvs egenskapens namn. För att sätta en mer användarvänlig etiektt kan antingen egenskapen LabelText ändras för kontrollen, men helst används en s k deskriptor på själva egenskapen:

  1. C#
  1. [Dynamix.Descriptors.UI.Label( "Fråga:" )]
  2. public string Question
  3. {
  4. get { return GetPropertyValue( p_Question ); }
  5. set { SetPropertyValue( p_Question, value ); }
  6. }

Egenskapsredigeraren hittar nu detta namn och visar det för redaktörerna och även i Visual Studios designer.

GeneralPropertyEditor för egenskapen Question (med etikett i deskriptor)

Redigerardelen av kontrollen

Vilken redigerarkontroll som används beror på egenskapens typ. Question är av typen string och Dynamix lägger då ut en TextBox för inmatning av värdet. GeneralPropertyEditor känner till typerna bool, string, int, DateTime, decimal och enum-typer. Men egenskaper av andra typer då? Bilder? Låt oss lägga till de övriga egenskaperna för QuestionAndAnswer:

 

GeneralPropertyEditor-kontoller för tre egenskaper

För bildegenskapen har det lagts ut en bildväljarkontroll (Dynamix.UI.Controls.ImageChooser). Anledningen är i det här fallet att klassen Dynamix.Image har en EditorControl-deskriptor enligt:

  1. C#
  1. using Dynamix.UI.Controls;
  2. [Serializable]
  3. [Dynamix.Descriptors.UI.EditorControl( typeof( ImageChooser ) )]
  4. public class Image : Dynamix.Object
  5. {
  6. ...
  7. }

När redigerarkontroll ska väljas kontrolleras först om det finns en EditorControl-deskriptor på själva egenskapen enligt:

  1. C#
  1. [Dynamix.Descriptors.UI.Label( "Fråga:" )]
  2. [Dynamix.Descriptors.UI.EditorControl( typeof( MyControl ) )]
  3. public string Question
  4. {
  5. get { return GetPropertyValue( p_Question ); }
  6. set { SetPropertyValue( p_Question, value ); }
  7. }

Därefter kontrolleras om returtypen själv har en EditorControl-deskriptor (som Dynamix.Image har i exemplet ovan). Om ingen redigerare hittas där heller och returvärdet inte är av de kända typerna kastas ett exception vid körning och designern visar:

Ladda och spara värden

Egenskapen DataMode är satt till AutoLoad i exemplem ovan. Detta innebär att GeneralPropertyEditor-kontrollen vid första laddningen kommer att leta efter egenskapen i det som formuläret (dvs omgivande IObjectContainer) anger som CurrentObject. De flesta redigeringsdialoger ärver från Dynamix.UI.Dialogs.EditObjectDialog och får därmed aktuellt objekt skickat till sig via ObjectState.

För att spara värden då redaktören har tryckt Ok kan man antingen låta kontrollen spara värdet själv med:

  1. C#
  1. uiQuestion.SaveValues()

eller läsa av värdet med uiQuestion.Value och själv sätta spara på lämpligt sätt.

Läs mer