2017-05-03 7 views
2

Brush型を(除外して)シリアライズできないというJson.NETのさまざまな質問と回答を読んだ後、私自身がJsonConverterを必要としていたことは明らかでした。しかし、私が立ち往生しているところでは、私はデータを扱うために中間のオブジェクトを使用していますが、ブラシのタイプによってさまざまな型付きオブジェクトが存在するため、型情報もJsonに格納する必要があると思いますただし、[JsonProperty(TypeNameHandling = TypeNameHandling.All)]を使用している場合は機能しません。JsonConverterを使用してさまざまな `Brush`型をシリアライズ/デシリアライズ

マイコンバータ:

public class BrushJsonConverter : JsonConverter 
{ 
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     object SerializableBrush = null; 
     if (value is SolidColorBrush) 
      SerializableBrush = new SerializableColorBrush(value as SolidColorBrush); 

     var jo = JObject.FromObject(SerializableBrush); 
     jo.WriteTo(writer); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, 
     JsonSerializer serializer) 
    { 
     // Load JObject from stream 
     var jObject = JObject.Load(reader); 

     dynamic SerializableBrush = JsonConvert.DeserializeObject(jObject.ToString()); 

     if (SerializableBrush is SerializableColorBrush) 
      return (SerializableBrush as SerializableColorBrush).ToBrush(); 
     else if (SerializableBrush is SerializableImageBrush) 
      return (SerializableBrush as SerializableImageBrush).ToBrush(); 
     else return null; 

    } 

    public override bool CanConvert(Type objectType) 
    { 
     return typeof(Brush).IsAssignableFrom(objectType); 
    } 
} 

マイゴー間でオブジェクト:

class SerializableColorBrush 
{ 
    public Color Color{ get; set; } 

    public SerializableColorBrush(SolidColorBrush Brush) 
    { 
     this.Color = Brush.Color; 
    } 

    public SolidColorBrush ToBrush() 
    { 
     SolidColorBrush brush = new SolidColorBrush(this.Color); 
     return brush; 
    } 
} 
class SerializableImageBrush 
{ 
    public ImageSource ImageSource { get; set; } 
    public TileMode TileMode { get; set; } 
    public Stretch Stretch { get; set; } 
    public AlignmentX AlignmentX { get; set; } 
    public AlignmentY AlignmentY { get; set; } 

    public SerializableImageBrush(ImageBrush Brush) 
    { 
     this.ImageSource = Brush.ImageSource; 
     this.TileMode = Brush.TileMode; 
     this.Stretch = Brush.Stretch; 
     this.AlignmentX = Brush.AlignmentX; 
     this.AlignmentY = Brush.AlignmentY; 
    } 

    public ImageBrush ToBrush() 
    { 
     ImageBrush brush = new ImageBrush(); 
     brush.ImageSource = ImageSource; 
     brush.TileMode = TileMode; 
     brush.Stretch = Stretch; 
     brush.AlignmentX = AlignmentX; 
     brush.AlignmentY = AlignmentY; 
     return brush; 
    } 
} 

直列化される例プロパティ:

私は迷っている
private Brush _WindowBG = SystemColors.AppWorkspaceBrush; 
    [JsonConverter(typeof(BrushJsonConverter))] 
    [JsonProperty(TypeNameHandling = TypeNameHandling.All)] 
    public Brush WindowBG { get { return _WindowBG; } set { if (value != _WindowBG) { _WindowBG = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("WindowBG")); } } } 

?そして私はこの方法で正しい方向に進んでいますか?

最終結果私は自分のアプリケーションのテーマデータをjsonに保存しようとしています。色、画像、またはグラデーション(まだ含まれていません)のいろいろなブラシを使用しています。

答えて

1

IMHOは、実装の多くを洗い出している別のルートを終了しました。

私の中継オブジェクトであったオブジェクトを保持しますが、実際にデータを格納するオブジェクトになりました。これらのオブジェクトは(使い易いように)基底クラスを継承します。代わりに、XAMLでブラシにオブジェクトを直接結合の

public class SerializableBrush 
{ 
    public virtual Brush ToBrush() 
    { 
     return null; 
    } 
} 

public class SerializableColorBrush : SerializableBrush 
{ 
    public Color Color{ get; set; } 

    public SerializableColorBrush(SolidColorBrush Brush) 
    { 
     this.Color = Brush.Color; 
    } 

    public override Brush ToBrush() 
    { 
     SolidColorBrush brush = new SolidColorBrush(this.Color); 
     return brush; 
    } 
} 
public class SerializableImageBrush : SerializableBrush 
{ 
    public ImageSource ImageSource { get; set; } 
    public TileMode TileMode { get; set; } 
    public Stretch Stretch { get; set; } 
    public AlignmentX AlignmentX { get; set; } 
    public AlignmentY AlignmentY { get; set; } 

    public SerializableImageBrush(ImageBrush Brush) 
    { 
     this.ImageSource = Brush.ImageSource; 
     this.TileMode = Brush.TileMode; 
     this.Stretch = Brush.Stretch; 
     this.AlignmentX = Brush.AlignmentX; 
     this.AlignmentY = Brush.AlignmentY; 
    } 

    public override Brush ToBrush() 
    { 
     ImageBrush brush = new ImageBrush(); 
     brush.ImageSource = ImageSource; 
     brush.TileMode = TileMode; 
     brush.Stretch = Stretch; 
     brush.AlignmentX = AlignmentX; 
     brush.AlignmentY = AlignmentY; 
     return brush; 
    } 
} 

はその後、私はブラシのに私のカスタム汎用オブジェクトを回しコンバータを作成した(これは、基本クラスは、物事が本当に簡単になります場所です)。私の新しいタイプを使用するために必要なブラシ情報を格納し

public class SerializableBrushToBrush : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return (value as Config.SerializableBrush).ToBrush(); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

もちろん私のテンプレートクラスは、私はまた、メインウィンドウが示された後、私はJSONを埋めた場合、私のテンプレートが表示されませんようOnDeserializedコールバックを追加しました。

public class Template : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    private SerializableBrush _WindowBG = new SerializableColorBrush(SystemColors.AppWorkspaceBrush); 
    [JsonProperty(TypeNameHandling = TypeNameHandling.All)] 
    public SerializableBrush WindowBG { get { return _WindowBG; } set { if (value != _WindowBG) { _WindowBG = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("WindowBG")); } } } 

    [OnDeserialized] 
    internal void OnDeserializedMethod(StreamingContext context) 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(string.Empty)); 
    } 

} 

もちろん、最終的に私のウィンドウは新しいコンバータを使用する必要がありました。

<Window.Resources> 
    <local:SerializableBrushToBrush x:Key="SerializableBrushToBrush"/> 
</Window.Resources> 
<Window.Background> 
    <Binding Converter="{StaticResource SerializableBrushToBrush}" Path="Template.WindowBG" Source="{x:Static config:Global.store}"/> 
</Window.Background> 

今私のJSONを操作するために、きれいと簡単に見える

"Template": { 
    "WindowBG": { 
     "$type": "Config.SerializableImageBrush, Config", 
     "ImageSource": "C:\\Users\\jhebb\\Pictures\\20150805_150241.jpg", 
     "TileMode": 0, 
     "Stretch": 1, 
     "AlignmentX": 1, 
     "AlignmentY": 1 
    }, 
    "WindowFG": { 
     "$type": "Config.SerializableColorBrush, Config", 
     "Color": "#FF000000" 
    }, 
    "DeviceBarBG": { 
     "$type": "Config.SerializableColorBrush, Config", 
     "Color": "#FFA0A0A0" 
    }, 
    "DeviceBarFG": { 
     "$type": "Config.SerializableColorBrush, Config", 
     "Color": "#FF000000" 
    }, 
    "WorkspaceBG": { 
     "$type": "Config.SerializableColorBrush, Config", 
     "Color": "#FFFFFFFF" 
    }, 
    "MainTabFG": { 
     "$type": "Config.SerializableColorBrush, Config", 
     "Color": "#FF000000" 
    }, 
    "MenuBG": { 
     "$type": "Config.SerializableColorBrush, Config", 
     "Color": "#FFF0F0F0" 
    }, 
    "MenuFG": { 
     "$type": "Config.SerializableColorBrush, Config", 
     "Color": "#FF000000" 
    } 
    } 
関連する問題