PowerTools SPREAD for Windows Forms 10.0J
カスタム複合シェイプの作成

すべてのシェイプクラスには、1つのシェイプ内に別のシェイプを埋め込むことができるという独自の機能があります。これは、複合シェイプを作成するための優れた機能です。ここでは、次の図のような、複数の組み込みシェイプの組み合わせでウォーターマークのように機能する、カスタム複合シェイプの作成方法について説明します。

カスタム複合シェイプの例

上図のカスタム複合シェイプを作成するには、CompanyWatermark という名前のカスタムシェイプクラスを定義し、各プロパティを設定して外観をカスタマイズします。このカスタムシェイプは、いくつかの要素を組み合わせて作成しています。背景色を特定の色から透明にグラデーション表示し、埋め込みシェイプによって企業ロゴイメージを表示し、独立した埋め込みテキストシェイプによって企業名を表示し、さらに追加情報(Web サイトアドレス、企業方針、セキュリティ分類など)を表示するテキストシェイプを表示しています。

カスタム クラスの派生

ここではまず、標準のRectangleShapeクラスからクラスを派生させます。これは、さまざまな埋め込みシェイプを配置するための、長方形の土台となります。楕円、多角形など、他の任意のシェイプを簡単に使用できます。ただし、埋め込むシェイプは親シェイプの境界を越えて表示されないため、境界を越えた部分の埋め込みシェイプは切り取られます。

プロパティの設定

次に、埋め込むシェイプにアクセスするためのプロパティを作成します。複合シェイプを作成することの利点の1つは、埋め込みシェイプの多数の不要なプロパティを非表示にできることです。カスタムプロパティを使用することで、必要な情報だけを公開できます。最初に作成するのは「CompanyColor」プロパティです。これは背景グラデーションの主要な色であり、主要シェイプ内で、特定の色から透明へと段階的に薄く表示されます。また、背後のシートが完全に隠れないように、アルファブレンドを行います。グラデーションクラスを使用すると、グラデーションの方向と種類を定義するStyleなど、他のプロパティも設定できます。この例では、GradientStyle.TopDownというStyle値を使用しています。

次に作成するのは、「CompanyLogo」という名前のイメージプロパティです。 このプロパティは、埋め込んだロゴシェイプ内に表示するイメージを設定します。 この例では、ウォーターマークの左上隅にロゴシェイプをロックします。ロゴの配置を設定する各プロパティを使用することで、この機能を簡単に拡張できます。

テキスト シェイプの埋め込み

ウォーターマークの最も重要な要素は、企業名です。これには、埋め込んだTextShapeオブジェクトを使用して、企業名を表します。これは、文字列の値を取る「CompanyName」プロパティによって、ウォーターマークシェイプ上に表示します。ここでは使用しませんが、TextShapeクラスにはこの他にもFontやForeColorなど、カスタマイズと公開が可能な多数の機能があります。また、サンプルを単純化するため、ウォーターマークシェイプの中央に企業名シェイプをロックします。

最後に、ウォーターマーク内に追加情報を表示するための、2番目のTextShapeオブジェクトを設定します。 追加情報には、企業方針、スローガン、Webサイトのアドレス、あるいは「CONFIDENTIAL」、「Copyright 2005」といったテキストを使用できます。ここでは、追加情報テキストをウォーターマークシェイプの左下隅に固定します。 この埋め込みシェイプには、他にも多数のプロパティを設定できます。 この例では、必要な項目だけを公開します。 このシェイプのテキストは、「CompanyText」プロパティによって公開します。

SPREADではビューポート ペインをスクロールできます。したがって、SPREADの TopChange および LeftChange イベントを上書きして、現在のシートに合わせてウォーターマークを移動させることで、ウォーターマークを常にスプレッドシートコントロール幅で、画面の最上部に表示できます。ウォーターマーク クラスの Top および Left プロパティも上書きし、各埋め込みオブジェクトを、ウォーターマーク内で常に表示されるように移動します。

サンプルコード

次のサンプルコードは、上図で示したカスタム複合シェイプを作成するCompanyWatermarkクラスの使用方法、および実装方法を示しています。

以下、CompanyWatermarkクラスを使用してシートに複合シェイプを追加する方法です。

C#
コードのコピー
private void Form1_Load(object sender, EventArgs e)
{
    CompanyWatermark test = new CompanyWatermark(0, 0, 550, 200);
    fpSpread1_Sheet1.AddShape(test);
}
Visual Basic
コードのコピー
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Dim test As New CompanyWatermark(0, 0, 550, 200)
    FpSpread1_Sheet1.AddShape(test)
End Sub

以下、CompanyWatermarkクラスの実装方法です。

C#
コードのコピー
using System;
using System.Drawing;
using System.Runtime.Serialization;
using FarPoint.Win;
using FarPoint.Win.Spread.DrawingSpace;
using System.Xml;
public class CompanyWatermark : RectangleShape, ISerializable
{
    private Color mCompanyColor = Color.Green;
    private Image mCompanyLogo = WatermarkShape.Properties.Resources.SampleLogo;
    private string mCompanyName = "[Company Name]";
    private string mCompanyText = "[Company Text]";
    internal CompanyWatermark() { } // required for ISerializeSupport
    public CompanyWatermark(int left, int top, int width, int height) : base()
    {
        CanRotate = false;
        SetBounds(left, top, width, height);
        UpdateChildren();
    }
    public CompanyWatermark(SerializationInfo info, StreamingContext context) : base(info, context)
    {
        mCompanyColor = (Color)info.GetValue("cc", typeof(Color));
        mCompanyLogo = (Image)info.GetValue("cl", typeof(Image));
        mCompanyName = info.GetString("cn");
        mCompanyText = info.GetString("ct");
        UpdateChildren();
    }
    public override void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        base.GetObjectData(info, context);
        info.AddValue("cc", mCompanyColor);
        info.AddValue("cl", mCompanyLogo);
        info.AddValue("cn", mCompanyName);
        info.AddValue("ct", mCompanyText);
    }
    public Color CompanyColor
    {
        get
        {
            return mCompanyColor;
        }
        set
        {
            mCompanyColor = value;
            UpdateChildren();
        }
    }
    public Image CompanyLogo
    {
        get
        {
            return mCompanyLogo;
        }
        set
        {
            mCompanyLogo = value;
            UpdateChildren();
        }
    }
    public string CompanyName
    {
        get
        {
            return mCompanyName;
        }
        set
        {
            mCompanyName = value;
            UpdateChildren();
        }
    }
    public string CompanyText
    {
        get
        {
            return mCompanyText;
        }
        set
        {
            mCompanyText = value;
            UpdateChildren();
        }
    }
    public override void Rotate(float angle)
    {
        base.Rotate(angle);
        foreach (PSShape shape in ContainedObjects)
            shape.RotationAngle = angle;
    }
    public override bool Deserialize(XmlNodeReader r)
    {
        bool inCompanyColor = false;
        bool inCompanyLogo = false;
        XmlDocument doc = new XmlDocument();
        XmlNode node;
        XmlNodeReader r2;
        XmlNodeReader r3;
        XmlNodeReader r4;
        r.MoveToElement();
        node = doc.ReadNode(r);
        r2 = new XmlNodeReader(node);
        r3 = new XmlNodeReader(node);
        r4 = new XmlNodeReader(node);
        PSObject.Deserialize(this, r2);
        PSShape.Deserialize(this, r3);
        while (r4.Read())
        {
            switch (r.NodeType)
            {
                case XmlNodeType.Element:
                    if (r.Name.Equals("CompanyColor"))
                        inCompanyColor = true;
                    else if (r.Name.Equals("CompanyLogo"))
                        inCompanyLogo = true;
                    else if (r.Name.Equals("CompanyName"))
                        mCompanyName = Serializer.DeserializeString(r);
                    else if (r.Name.Equals("CompanyText"))
                        mCompanyText = Serializer.DeserializeString(r);
                    break;
                case XmlNodeType.Text:
                    if (inCompanyColor)
                        mCompanyColor = Serializer.DeserializeColorValue(r.Value);
                    else if (inCompanyLogo)
                        mCompanyLogo = Serializer.DeserializeImage(r.Value);
                    break;
                case XmlNodeType.EndElement:
                    if (inCompanyColor && r.Name.Equals("CompanyColor"))
                        inCompanyColor = false;
                    else if (inCompanyLogo && r.Name.Equals("CompanyLogo"))
                        inCompanyLogo = false;
                    break;
            }
        }
        return true;
    }
    public override bool Serialize(XmlTextWriter w)
    {
        w.WriteStartElement("PSShape");
        w.WriteAttributeString("class", this.GetType().FullName);
        w.WriteAttributeString("assembly", this.GetType().Assembly.FullName);
        PSShape.Serialize(this, w);
        Serializer.SerializeColor(mCompanyColor, "CompanyColor", w);
        Serializer.SerializeImage(mCompanyLogo, "CompanyLogo", w);
        Serializer.SerializeString(mCompanyName, "CompanyName", w);
        Serializer.SerializeString(mCompanyText, "CompanyText", w);
        w.WriteEndElement();  // object
        return true;
    }
    private void UpdateChildren()
    {
        ShapeOutlineThickness = 0;
        if( ContainedObjects.Count == 0 )
        {   // create the child shapes
            // gradient effect for company color
            BackColor = Color.Transparent;
            Gradient.Sections = new GradientSection[] { new GradientSection(mCompanyColor, 255, 200), new GradientSection(Color.White, 255, 255) };
            Gradient.Style = GradientStyle.LinearTopDown;
            // company logo is aligned to left and uses image width and height to align company text below
            RectangleShape logo = new RectangleShape();
            logo.BackColor = Color.Transparent;
            logo.ShapeOutlineThickness = 0;
            logo.SetBounds(0, 0, mCompanyLogo.Width, mCompanyLogo.Height);
            logo.Picture = mCompanyLogo;
            logo.PictureTransparencyColor = Color.White;
            ContainedObjects.Add(logo);
            TextShape name = new TextShape();
            name.Text = mCompanyName;
            name.ForeColor = Color.Orange;
            name.ShapeOutlineColor = Color.Black;
            name.ShapeOutlineStyle = System.Drawing.Drawing2D.DashStyle.Solid;
            name.ShapeOutlineThickness = 1;
            ContainedObjects.Add(name);
            name.SetBounds(logo.Width + 5, (logo.Height - name.Height) / 2, name.Width, name.Height);
            TextShape text = new TextShape();
            text.Text = mCompanyText;
            text.ForeColor = Color.Red;
            text.ShapeOutlineColor = Color.Black;
            text.ShapeOutlineStyle = System.Drawing.Drawing2D.DashStyle.Solid;
            text.ShapeOutlineThickness = 1;
            ContainedObjects.Add(text);
            text.SetBounds(0, logo.Height + 5, text.Width, text.Height);
        }
        else
        {   // update the child shapes
            RectangleShape logo = (RectangleShape)ContainedObjects[0];
            TextShape name = (TextShape)ContainedObjects[1];
            TextShape text = (TextShape)ContainedObjects[2];
            Gradient.Sections = new GradientSection[] { new GradientSection(mCompanyColor, 50), new GradientSection(Color.White, 50) };
            logo.Picture = mCompanyLogo;
            name.Text = mCompanyName;
            text.Text = mCompanyText;
        }
    }
}
Visual Basic
コードのコピー
Imports System.Runtime.Serialization
Imports System.Xml
Imports FarPoint.Win
Imports FarPoint.Win.Spread.DrawingSpace
<Serializable()> Public Class CompanyWatermark
    Inherits RectangleShape
    Implements ISerializable
    Private mCompanyColor As Color = Color.Green
    Private mCompanyLogo As Image = My.Resources.SampleLogo
    Private mCompanyName As String = "[Company Name]"
    Private mCompanyText As String = "[Company Text]"
    Friend Sub New()
    End Sub
    ' required for ISerializeSupport
    Public Sub New(left As Integer, top As Integer, width As Integer, height As Integer)
        MyBase.New()
        CanRotate = False
        SetBounds(left, top, width, height)
        UpdateChildren()
    End Sub
    Public Sub New(info As SerializationInfo, context As StreamingContext)
        MyBase.New(info, context)
        mCompanyColor = DirectCast(info.GetValue("cc", GetType(Color)), Color)
        mCompanyLogo = DirectCast(info.GetValue("cl", GetType(Image)), Image)
        mCompanyName = info.GetString("cn")
        mCompanyText = info.GetString("ct")
        UpdateChildren()
    End Sub
    Public Overrides Sub GetObjectData(info As SerializationInfo, context As StreamingContext)
        MyBase.GetObjectData(info, context)
        info.AddValue("cc", mCompanyColor)
        info.AddValue("cl", mCompanyLogo)
        info.AddValue("cn", mCompanyName)
        info.AddValue("ct", mCompanyText)
    End Sub
    Public Property CompanyColor() As Color
        Get
            Return mCompanyColor
        End Get
        Set
            mCompanyColor = Value
            UpdateChildren()
        End Set
    End Property
    Public Property CompanyLogo() As Image
        Get
            Return mCompanyLogo
        End Get
        Set
            mCompanyLogo = Value
            UpdateChildren()
        End Set
    End Property
    Public Property CompanyName() As String
        Get
            Return mCompanyName
        End Get
        Set
            mCompanyName = Value
            UpdateChildren()
        End Set
    End Property
    Public Property CompanyText() As String
        Get
            Return mCompanyText
        End Get
        Set
            mCompanyText = Value
            UpdateChildren()
        End Set
    End Property
    Public Overrides Sub Rotate(angle As Single)
        MyBase.Rotate(angle)
        For Each shape As PSShape In ContainedObjects
            shape.RotationAngle = angle
        Next
    End Sub
    Public Overrides Function Deserialize(r As XmlNodeReader) As Boolean
        Dim inCompanyColor As Boolean = False
        Dim inCompanyLogo As Boolean = False
        Dim doc As New XmlDocument()
        Dim node As XmlNode
        Dim r2 As XmlNodeReader
        Dim r3 As XmlNodeReader
        Dim r4 As XmlNodeReader
        r.MoveToElement()
        node = doc.ReadNode(r)
        r2 = New XmlNodeReader(node)
        r3 = New XmlNodeReader(node)
        r4 = New XmlNodeReader(node)
        PSObject.Deserialize(Me, r2)
        PSShape.Deserialize(Me, r3)
        While r4.Read()
            Select Case r.NodeType
                Case XmlNodeType.Element
                    If r.Name.Equals("CompanyColor") Then
                        inCompanyColor = True
                    ElseIf r.Name.Equals("CompanyLogo") Then
                        inCompanyLogo = True
                    ElseIf r.Name.Equals("CompanyName") Then
                        mCompanyName = Serializer.DeserializeString(r)
                    ElseIf r.Name.Equals("CompanyText") Then
                        mCompanyText = Serializer.DeserializeString(r)
                    End If
                    Exit Select
                Case XmlNodeType.Text
                    If inCompanyColor Then
                        mCompanyColor = Serializer.DeserializeColorValue(r.Value)
                    ElseIf inCompanyLogo Then
                        mCompanyLogo = Serializer.DeserializeImage(r.Value)
                    End If
                    Exit Select
                Case XmlNodeType.EndElement
                    If inCompanyColor AndAlso r.Name.Equals("CompanyColor") Then
                        inCompanyColor = False
                    ElseIf inCompanyLogo AndAlso r.Name.Equals("CompanyLogo") Then
                        inCompanyLogo = False
                    End If
                    Exit Select
            End Select
        End While
        Return True
    End Function
    Public Overrides Function Serialize(w As XmlTextWriter) As Boolean
        w.WriteStartElement("PSShape")
        w.WriteAttributeString("class", Me.[GetType]().FullName)
        w.WriteAttributeString("assembly", Me.[GetType]().Assembly.FullName)
        PSShape.Serialize(Me, w)
        Serializer.SerializeColor(mCompanyColor, "CompanyColor", w)
        Serializer.SerializeImage(mCompanyLogo, "CompanyLogo", w)
        Serializer.SerializeString(mCompanyName, "CompanyName", w)
        Serializer.SerializeString(mCompanyText, "CompanyText", w)
        w.WriteEndElement()
        ' object
        Return True
    End Function
    Private Sub UpdateChildren()
        ShapeOutlineThickness = 0
        If ContainedObjects.Count = 0 Then
            ' create the child shapes
            ' gradient effect for company color
            BackColor = Color.Transparent
            Gradient.Sections = New GradientSection() {New GradientSection(mCompanyColor, 255, 200), New GradientSection(Color.White, 255, 255)}
            Gradient.Style = GradientStyle.LinearTopDown
            ' company logo is aligned to left and uses image width and height to align company text below
            Dim logo As New RectangleShape()
            logo.BackColor = Color.Transparent
            logo.ShapeOutlineThickness = 0
            logo.SetBounds(0, 0, mCompanyLogo.Width, mCompanyLogo.Height)
            logo.Picture = mCompanyLogo
            logo.PictureTransparencyColor = Color.White
            ContainedObjects.Add(logo)
            Dim name As New TextShape()
            name.Text = mCompanyName
            name.ForeColor = Color.Orange
            name.ShapeOutlineColor = Color.Black
            name.ShapeOutlineStyle = System.Drawing.Drawing2D.DashStyle.Solid
            name.ShapeOutlineThickness = 1
            ContainedObjects.Add(name)
            name.SetBounds(logo.Width + 5, (logo.Height - name.Height) / 2, name.Width, name.Height)
            Dim text As New TextShape()
            text.Text = mCompanyText
            text.ForeColor = Color.Red
            text.ShapeOutlineColor = Color.Black
            text.ShapeOutlineStyle = System.Drawing.Drawing2D.DashStyle.Solid
            text.ShapeOutlineThickness = 1
            ContainedObjects.Add(text)
            text.SetBounds(0, logo.Height + 5, text.Width, text.Height)
        Else
            ' update the child shapes
            Dim logo As RectangleShape = DirectCast(ContainedObjects(0), RectangleShape)
            Dim name As TextShape = DirectCast(ContainedObjects(1), TextShape)
            Dim text As TextShape = DirectCast(ContainedObjects(2), TextShape)
            Gradient.Sections = New GradientSection() {New GradientSection(mCompanyColor, 50), New GradientSection(Color.White, 50)}
            logo.Picture = mCompanyLogo
            name.Text = mCompanyName
            text.Text = mCompanyText
        End If
    End Sub
End Class
関連トピック

 

 


© 2004-2017, GrapeCity inc. All rights reserved.