1

DrawingBrushを含むBL構造をシリアル化する必要があります。私はそれを次のように書き直しました:

[ProtoContract]
public class BaseProtoBuf : INotifyPropertyChanged, IFormattable
{
    [ProtoMember(1)]
    public string ID { get; set; }
    // Bunch of properties of .net primitive types
    // ..
    private DrawingBrush _geometry;
    [ProtoMember(9)]
    [Browsable(false)]
    public DrawingBrush Geometry
    {
            get { return _geometry; }
            set
            {
                _geometry = value; 
                ScaleDrawing();
            }
    }
}
[ProtoContract]
[ProtoInclude(1, typeof(string))]
// All other includes
[ProtoInclude(9, typeof(DrawingBrush)]
public class DerivedProtoBuf : BaseProtoBuf, ICloneable
{        
    // Some additional properties of primitive types, annotated starting with ProtoMember 10 and so on
}

シリアル化するには、次のコードを実行しています:

const string fileName = "Protobuf.bin";
using (var file = File.Create(fileName))
{
    file.Position = 0;
    var testBase = new BaseProtoBuf
                                   {
                                      Height = 100,
                                      Width = 100,
                                      Name = "Test 1",
                                      OffsetX = 200,
                                      OffsetY = 200,
                                      Geometry = sourceList[0].Geometry // some not-null DrawingBrush
                                  };
    Serializer.Serialize(file, testBase);
    file.Position = 0;
    var restored = Serializer.Deserialize<BaseProtoBuf>>(file);
}
}

Derivedクラスオブジェクトをシリアル化する必要がありますが、Baseシリアル化中に、「適切なデフォルトのDrawingBrushエンコーディングが見つかりません」というメッセージが表示されます。一部のオブジェクトではDrawingBrushがnullになる可能性があるためだと思いましたが、テスト1ではそうではありません。適切にシリアル化するための回避策1)nullでないDrawingBrushを使用するベースオブジェクト2)nullのDrawingBrushを使用する派生オブジェクト?前もって感謝します。

4

2 に答える 2

3

単純な WPF Brush をシリアル化するための正しい RuntimeTypeModel 構成:

RuntimeTypeModel.Default.Add(typeof(Brush), false)
               .AddSubType(300, typeof(SolidColorBrush));
RuntimeTypeModel.Default.Add(typeof(SolidColorBrush), false)
                .Add("Color");
RuntimeTypeModel.Default.Add(typeof(Color), false)
                .Add("A", "R", "G", "B"); // needed for proper color serialization
RuntimeTypeModel.Default.Add(typeof(SolidColorBrush), false)
        .Add("Color");
RuntimeTypeModel.Default.Add(typeof(DrawingBrush), false)
        .Add("Stretch", "Drawing");
RuntimeTypeModel.Default.Add(typeof(Drawing), false)
        .AddSubType(100, typeof(DrawingGroup))
        .AddSubType(200, typeof(GeometryDrawing));
RuntimeTypeModel.Default.Add(typeof(DrawingGroup), false)
        .Add("Children");
RuntimeTypeModel.Default.Add(typeof(Pen), false)
        .Add("Brush", "Thickness", "LineJoin");
RuntimeTypeModel.Default.Add(typeof(GeometryDrawing), false)
       .Add("Brush", "Geometry", "Pen");
于 2012-05-04T12:07:38.233 に答える
2

コントラクトが定義されていないため、 DrawingBrush はすぐにシリアライズ可能ではありません。ここにさまざまなオプションがあります:

  • タイプがかなり単純な場合は、必要に応じてプロパティ/サブタイプなどを追加して、RuntimeTypeModel を介して実行時にコントラクトを構成できます。
  • 場合によっては、「サロゲート」 (オンザフライ DTO として機能するために使用される双方向変換演算子を持つ型) の使用が推奨される場合があります。サロゲートは、RuntimeTypeModel を介して指定できます。「サロゲート」を使用すると、既存のモデルを使用できますが、必要に応じて DTO タイプを交換できます
  • それ以外の場合は、モデル内のフレームワーク固有の型を避けることを検討し、必要な情報で DTO 型を使用してください。そこから、実行時にフレームワークに必要な値を構築します
于 2012-04-28T08:05:01.703 に答える