Bagikan melalui


Menyesuaikan Bidang Teks dan Gambar

Saat Anda menentukan dekorator teks dalam bentuk, bentuk tersebut direpresentasikan dengan TextField. Untuk contoh inisialisasi TextFields dan ShapeFields lainnya, periksa Dsl\GeneratedCode\Shapes.cs dalam solusi bahasa khusus domain Anda.

TextField adalah objek yang mengelola area dalam bentuk, seperti ruang yang ditetapkan ke label. Satu instans TextField dibagikan di antara banyak bentuk dari kelas yang sama. Instans TextField tidak menyimpan teks label secara terpisah untuk setiap instans: sebagai gantinya, metode GetDisplayText(ShapeElement) mengambil bentuk sebagai parameter, dan dapat mencari teks bergantung pada status bentuk saat ini dan elemen modelnya.

Cara tampilan bidang teks ditentukan

Metode DoPaint() dipanggil untuk menampilkan bidang di layar. Anda dapat mengganti DoPaint(), default atau mengganti beberapa metode yang dipanggil. Versi sederhana dari metode default berikut dapat membantu Anda memahami cara mengganti perilaku default:

// Simplified version:
public override void DoPaint(DiagramPaintEventArgs e, ShapeElement parentShape)
{
  string text = GetDisplayText(shape);
  StringFormat format = GetStringFormat(parentShape);
  Brush brush = GetTextBrush(e.View, shape);
  using (Font font = GetFont(shape))
  {
    e.Graphics.DrawString(text, font, brush, format);
  }
}
// StringFormat determines whether the string is centered etc.
// To customize statically for all instances of this shape field,
// assign to DefaultStringFormat.
// To customize dynamically or per shape, override this:
public virtual StringFormat GetStringFormat(ShapeElement shape)
{ return DefaultStringFormat; }

// Override to customize the displayed string:
public virtual string GetDisplayText(ShapeElement shape)
{ return this.GetValue(shape).ToString(); }

// Brush determines the text color.
// To change the brush for every field, change the shape's styleset.
// To customize to a brush in the style set, override GetTextBrushId.
// To change the brush to non-standard color, override this.
// Should take account of whether selected.
public virtual Brush GetTextBrush(DiagramClientView view, ShapeElement shape)
{ return shape.StyleSet.GetBrush(this.GetTextBrushId(view, shape)); }

// Brush ID selects a brush from a StyleSet.
// Either return a member of DiagramBrushes
// or add your own brush to the shape or application's styleset.
// Override this to change dynamically or per instance.
// To change statically, just assign to default values.
public virtual StyleSetResourceId GetTextBrushId(DiagramClientView view, ShapeElement shape)
{ return IsSelected(view, shape) ? (view.Focused ? DefaultSelectedTextBrushId
: DefaultInactiveSelectedTextBrushId ) : DefaultTextBrushId ;
}

// Font determines the shape and size of the text.
// To change the font for every field, change the shape's styleset.
// To customize to a font in the style set, override GetFontId.
// To change the font to a non-standard font, override this.
public virtual Font GetFont(ShapeElement shape)
{ return shape.StyleSet.GetFont(GetFontId(shape)); }

// Selects a font from a styleset.
// Either return a member of DiagramFonts or
// add your own font to the shape or application's styleset.
// To change statically for all instances of this field,
// assign to DefaultFontId.
// To change per shape or dynamically, override this.
public virtual StyleSetResourceId GetFontId(ShapeElement parentShape)
{ return DefaultFontId; }

Ada beberapa pasangan metode Get dan properti Default lainnya, seperti DefaultMultipleLine/GetMultipleLine(). Anda dapat menetapkan nilai ke properti Default untuk mengubah nilai untuk semua instans bidang bentuk. Untuk membuat nilai bervariasi dari satu instans bentuk ke instans bentuk lainnya, atau bergantung pada status bentuk atau elemen modelnya, ganti metode Get.

Penyesuaian statik

Jika Anda ingin mengubah setiap instans bidang bentuk ini, pertama-tama cari tahu apakah Anda dapat mengatur properti di Definisi Bahasa Khusus Domain. Misalnya, Anda dapat mengatur ukuran dan gaya fon di jendela Properti.

Jika tidak, ganti metode InitializeShapeFields dari kelas bentuk Anda, dan tetapkan nilai ke properti Default... yang sesuai dari bidang teks.

Peringatan

Untuk mengganti InitializeShapeFields(), Anda harus mengatur properti Menghasilkan Turunan Ganda dari kelas bentuk ke true dalam Definisi Bahasa Khusus Domain.

Dalam contoh ini, bentuk memiliki bidang teks yang akan digunakan untuk komentar pengguna. Kita akan menggunakan fon komentar standar. Karena fon komentar standar adalah fon standar dari kumpulan gaya, kita dapat mengatur id fon default:


 partial class ExampleShape
{   protected override void InitializeShapeFields(IList<ShapeField> shapeFields)
    {
      // Fields set up according to DSL Definition:
      base.InitializeShapeFields(shapeFields);
      // Find and update comment field:
      TextField commentField = ShapeElement.FindShapeField(shapeFields, "CommentDecorator") as TextField;
      // Use the standard font for comments:
      commentField.DefaultFontId = DiagramFonts.CommentText;

Penyesuaian dinamis

Untuk membuat tampilan bervariasi bergantung pada status bentuk atau elemen modelnya, dapatkan subkelas Anda sendiri dari TextField dan ganti satu atau beberapa metode Get.... Anda juga harus mengganti metode InitializeShapeFields bentuk Anda, dan mengganti instans TextField dengan instans kelas Anda sendiri.

Contoh berikut membuat fon bidang teks bergantung pada status properti domain Boolean dari elemen model bentuk.

Untuk menjalankan kode contoh ini, buat solusi Bahasa Khusus Domain baru menggunakan template Bahasa Minimal. Tambahkan properti domain Boolean AlternateState ke kelas domain ExampleElement. Tambahkan dekorator ikon ke kelas ExampleShape, dan atur gambar dekorator ikon ke file bitmap. Klik Transformasi Semua Templat. Tambahkan file kode baru di proyek Bahasa Khusus Domain, dan masukkan kode berikut.

Untuk menguji kode, tekan F5 dan, dalam solusi penelusuran kesalahan, buka diagram sampel. Status default ikon akan muncul. Pilih bentuk dan di jendela Properti, ubah nilai properti AlternateState. Fon nama elemen harus berubah.

using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Diagrams;
...

  partial class ExampleShape
  {
    /// <summary>
    /// Compose a list of the fields in this shape.
    /// Called once for each shape class.
    /// </summary>
    protected override void InitializeShapeFields(IList<ShapeField> shapeFields)
    {
      // Fields set up according to DSL Definition:
      base.InitializeShapeFields(shapeFields);
      // Replace the text field for NameDecorator:
      TextField oldField = ShapeElement.FindShapeField(shapeFields, "NameDecorator") as TextField;
      shapeFields.Remove(oldField);
      // Replace with my text field based on DSL Definition values:
      MyTextField newField = new MyTextField(oldField);
      shapeFields.Add(newField);
    }
  }
  /// <summary>
  /// Dynamic font depends on state of model element.
  /// </summary>
  public class MyTextField : TextField
  {
    public MyTextField(TextField prototype)
      : base(prototype.Name)
    {
      DefaultText = prototype.DefaultText;
      DefaultFocusable = prototype.DefaultFocusable;
      DefaultAutoSize = prototype.DefaultAutoSize;
      AnchoringBehavior.MinimumHeightInLines = prototype.AnchoringBehavior.MinimumHeightInLines;
      AnchoringBehavior.MinimumWidthInCharacters = prototype.AnchoringBehavior.MinimumWidthInCharacters;
      DefaultAccessibleState = prototype.DefaultAccessibleState;
    }

    public override System.Drawing.Font GetFont(ShapeElement parentShape)
    {
      // Access the Boolean domain property of the model element:
      if ((parentShape.ModelElement as ExampleElement).AlternateState)
        return new System.Drawing.Font("Callisto", 14.0f,
               System.Drawing.FontStyle.Italic |
               System.Drawing.FontStyle.Bold);
      else
        return base.GetFont(parentShape);
    }

  }

Kumpulan gaya

Contoh sebelumnya memperlihatkan cara Anda dapat mengubah bidang teks ke fon apa pun yang tersedia. Tetapi, metode yang lebih disukai adalah mengubah bidang teks ke salah satu kumpulan gaya yang dikaitkan dengan bentuk atau dengan aplikasi. Untuk melakukan hal ini, Anda mengganti GetFontId atau GetTextBrushId().

Atau, pertimbangkan untuk mengubah kumpulan gaya bentuk Anda dengan mengganti InitializeResources. Ini memiliki efek mengubah fon dan kuas untuk semua bidang bentuk.

Menyesuaikan Bidang Gambar

Saat Anda menentukan dekorator gambar dalam bentuk, dan saat Anda menentukan bentuk gambar, area tempat bentuk ditampilkan akan dikelola oleh ImageField. Untuk contoh inisialisasi ImageFields dan ShapeFields lainnya, periksa Dsl\GeneratedCode\Shapes.cs dalam solusi Bahasa Khusus Domain Anda.

ImageField adalah objek yang mengelola area dalam bentuk, seperti ruang yang ditetapkan untuk dekorator. Satu instans ImageField dibagikan di antara banyak bentuk dari kelas bentuk yang sama. Instans ImageField tidak menyimpan gambar terpisah untuk setiap bentuk: sebagai gantinya, metode GetDisplayImage(ShapeElement) mengambil bentuk sebagai parameter, dan dapat mencari gambar bergantung pada status bentuk saat ini dan elemen modelnya.

Jika Anda menginginkan perilaku khusus seperti gambar variabel, Anda dapat membuat kelas Anda sendiri yang berasal dari ImageField.

Untuk membuat subkelas dari ImageField

  1. Atur properti Menghasilkan Turunan Ganda dari kelas bentuk induk dalam Definisi Bahasa Khusus Domain Anda.

  2. Ganti metode InitializeShapeFields dari kelas bentuk Anda.

    • Buat file kode baru di proyek Bahasa Khusus Domain, dan tulis definisi kelas parsial untuk kelas bentuk. Ganti definisi metode di sana.
  3. Periksa kode InitializeShapeFields di DSL\GeneratedCode\Shapes.cs.

    Dalam metode penggantian Anda, panggil metode dasar dan kemudian buat instans dari kelas bidang gambar Anda sendiri. Gunakan ini untuk mengganti bidang gambar biasa dalam daftar shapeFields.

Ikon dinamis

Contoh ini membuat perubahan ikon bergantung pada status elemen model bentuk.

Peringatan

Contoh ini menunjukkan cara membuat dekorator gambar dinamis. Tetapi jika Anda hanya ingin beralih di antara satu atau dua gambar bergantung pada status variabel model, akan lebih mudah untuk membuat beberapa dekorator gambar, menempatkannya di posisi yang sama pada bentuk, lalu mengatur filter Visibilitas agar bergantung pada nilai tertentu dari variabel model. Untuk mengatur filter ini, pilih peta bentuk di Definisi Bahasa Khusus Domain, buka jendela Detail Bahasa Khusus Domain, dan klik tab Dekorator.

Untuk menjalankan kode contoh ini, buat solusi Bahasa Khusus Domain baru menggunakan template Bahasa Minimal. Tambahkan properti domain Boolean AlternateState ke kelas domain ExampleElement. Tambahkan dekorator ikon ke kelas ExampleShape, dan atur gambar dekorator ikon ke file bitmap. Klik Transformasi Semua Templat. Tambahkan file kode baru di proyek Bahasa Khusus Domain, dan masukkan kode berikut.

Untuk menguji kode, tekan F5 dan, dalam solusi penelusuran kesalahan, buka diagram sampel. Status default ikon akan muncul. Pilih bentuk dan di jendela Properti, ubah nilai properti AlternateState. Ikon kemudian akan terlihat diputar 90 derajat, pada bentuk tersebut.

using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Diagrams;
...
partial class ExampleShape
{
    /// <summary>
    /// Compose a list of the fields in this shape.
    /// Called once for each shape class.
    /// </summary>
    /// <param name="shapeFields"></param>
    protected override void InitializeShapeFields(IList<ShapeField> shapeFields)
    {
      // Fields set up according to DSL Definition:
      base.InitializeShapeFields(shapeFields);

      // Replace the image field:
      ShapeField oldField = ShapeElement.FindShapeField(shapeFields, "IconDecorator");
      shapeFields.Remove(oldField);
      // Must keep the same name:
      MyImageField newField = new MyImageField(oldField.Name);
      shapeFields.Add(newField);
      newField.DefaultImage = (oldField as ImageField).DefaultImage.Clone() as System.Drawing.Image;
    }
  }

  public class MyImageField : ImageField
  {
    public MyImageField(string tag) : base(tag) { }

    /// <summary>
    /// Get the image for this field in the given shape.
    /// </summary>
    public override System.Drawing.Image GetDisplayImage(ShapeElement parentShape)
    {
      ExampleElement element = parentShape.ModelElement as ExampleElement;
      if (element.AlternateState == true)
        return AlternateImage;
      else
        return base.GetDisplayImage(parentShape);
    }

    private System.Drawing.Image alternateImage;
    public System.Drawing.Image AlternateImage
    {
      get
      {
        if (alternateImage == null)
        {
          // Alternate image is a copy of the default, rotated by 90 degrees:
          alternateImage = this.DefaultImage.Clone() as System.Drawing.Image;
          alternateImage.RotateFlip(System.Drawing.RotateFlipType.Rotate90FlipNone);
        }
        return alternateImage;
      }
    }
  }
}