0

ユーザーがテキストボックスを作成し、Windowsフォームのパネルに画像をドラッグアンドドロップできるプログラムがあります。ここで、ユーザーは画像を移動、サイズ変更、削除などを行うことができます。基本的には非常に単純な画像エディター。

私がやりたいことは、これを非常に単純な PowerPoint プログラムのように動作させることです。

ユーザーがこれらの画像 (ピクチャ ボックス内) とテキスト ボックスを含むパネルの内容を保存できるかどうかを調べています。次に、パネルをクリアして新しい画像とテキストでやり直しますが、必要に応じて前のパネルに戻って編集します。

したがって、プログラムの各パネルは、基本的に PowerPoint のスライドです。

現時点では、パネルを Jpeg として保存して保存できますが、この方法ではパネルをリロードしてコンテンツをパネルのように編集することはできません。

状況をある程度理解できるように説明できたことを願っています。

私が試みていることを行うことは可能ですか、それとも問題に別の方法でアプローチする必要がありますか?

4

2 に答える 2

5

私がこれを行う方法は、スライドを構成するすべての情報を格納するクラスを定義し (そのため、コードでスライドを表すことができる)、プレゼンテーションと呼ばれるスライドのリストをシリアル化することです。 XML ファイル。

各スライドには、画像、テキストボックスなど、さまざまな数のコントロールがあるため、最初にコントロールを定義しましょう。

public class MySlideClass
{
    public class Control
    {
        public Point Position       { get; set; }
        public Size  Size           { get; set; }
        public Color Background     { get; set; }
        public Color Forground      { get; set; }
        public Image Picture        { get; set; }
        public string Text          { get; set; }
        public float TextSize       { get; set; }
        public Point TextPosition   { get; set; }
        // ...
        public float Transparency   { get; set; }
        public bool  Visible        { get; set; }

        public Control()
        {
        }
    }

    public class Slide
    {
        [XmlAttribute]
        public string Name          { get; set; }
        //
        public string Title         { get; set; }
        public Size Size            { get; set; }
        public Color Background     { get; set; }
        public Color Forground      { get; set; }
        public float Transparency   { get; set; }
        public bool Visible         { get; set; }

        public List<Control> Children { get; set; }

        public Slide()
        {
        }
    }


    public MySlideClass()
    {
    }
}

明らかに、必要に応じてプロパティを追加/削除できます。

{ get; set; }and 空のデフォルト コンストラクタに注意してください。クラスは、パブリック プロパティ (get/set で定義された変数) で構成XMLSerializerされ、クラスをシリアル化できるように空の既定のコンストラクターを持っている必要があります (空でない他のコンストラクターを指定することもできます)。

次のようにクラスを使用します。

public void SaveSlideTest()
{
    // New control
    MySlideClass.Control newControl = new MySlideClass.Control();
    newControl.Position = new Point(20,30);
    newControl.Size     = new Size(75,25);
    newControl.Text     = "Image1";
    newControl.TextPosition= new Point(0,25);
    //ctl.Picture       = new Bitmap("image1.bmp");

    // Add control to children list
    List<MySlideClass.Control> childrenControls = new List<MySlideClass.Control>();
    childrenControls.Add(newControl);

    // New slide
    MySlideClass.Slide newSlide = new MySlideClass.Slide();
    newSlide.Name   = "Slide1";
    newSlide.Title  = "New Slide";
    newSlide.Size   = new Size(200,100);
    // Add child controls to slide
    newSlide.Children = childrenControls;

    // Add slide to presentation or 'slideshow'
    List<MySlideClass.Slide> mySlidePresentation = new List<MySlideClass.Slide>();
    mySlidePresentation.Add( newSlide );

    // Save presentation to XML
    SerializeObject("SavedSlidePresentation.xml",mySlidePresentation);
}

あなたの SavedSlidePresentation.xml は次のようになります。

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfSlide xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Slide Name="Slide1">
    <Title>New Slide</Title>
    <Size>
      <Width>200</Width>
      <Height>100</Height>
    </Size>
    <Background />
    <Forground />
    <Transparency>0</Transparency>
    <Visible>false</Visible>
    <Children>
      <Control>
        <Position>
          <X>20</X>
          <Y>30</Y>
        </Position>
        <Size>
          <Width>75</Width>
          <Height>25</Height>
        </Size>
        <Background />
        <Forground />
        <Text>Image1</Text>
        <TextSize>0</TextSize>
        <TextPosition>
          <X>0</X>
          <Y>25</Y>
        </TextPosition>
        <Transparency>0</Transparency>
        <Visible>false</Visible>
      </Control>
    </Children>
  </Slide>
</ArrayOfSlide>

シリアライズ/デシリアライズ関数は次のとおりです。

public static List<MySlideClass.Slide> DeserializePresentation(string FileName)
{
    List<MySlideClass.Slide> returnList = new List<MySlideClass.Slide>();

    using(StreamReader streamReader = new StreamReader(FileName))
    {
        XmlSerializer xmlReader = new XmlSerializer(typeof(List<MySlideClass.Slide>));
        returnList = (List<MySlideClass.Slide>) xmlReader.Deserialize(streamReader);
    }
    return returnList;
}

// A generic object serializer
public static void SerializeObject(string Filename,object Obj)
{
    using(StreamWriter streamWriter = new StreamWriter(Filename))
    {
        XmlSerializer xmlSerializer = new XmlSerializer(Obj.GetType());
        xmlSerializer.Serialize(streamWriter,Obj);
    }
}

これは よりも堅牢である必要がありますDictionary<TKey,TValue>

注意すべき重要な点の 1 つは、プロパティを Slide または Control クラスに追加することにした場合、デシリアライザーは古いバージョンのデータ クラスを使用して XML ファイルを逆シリアル化することができなくなります。

その場合、1) 古いバージョンの XML ファイルを手動または別の方法で変換するか、2)ISerializableクラスにインターフェイスを実装する (推奨) ことができます。

于 2013-07-08T18:43:54.703 に答える
1

以前に同様の種類のプロジェクトを作成し、すべてのデータを保持するために2つの辞書を作成しました

// Dictionary which Holds all the Info for the shapes in a Particular Slide
Dictionary<Int32, ShapeInfo> slideInfoDict = new Dictionary<Int32, ShapeInfo>();

// Dictionary which Holds all the Info for the all the shapes in the all the slides
Dictionary<Int32, SlideInfo> appInfoDict = new Dictionary<Int32, SlideInfo>();

私の「ShapeInfo」クラスには、さまざまな形状 (Table、Rect、Image など) に関するすべての情報があります。この shapeInfoDict のキー (Int32) は、選択された形状でした。

クラス「SlideInfo」は、その特定のスライドに関するすべての情報を保持します。このslideInfoDictのキー(Int32)はSlideを選択しました。

お役に立てば幸いです。

于 2013-07-08T11:17:25.563 に答える