2017-05-03 193 views
2

因此,在閱讀關於Json.NET無法(去)序列化Brush類型的各種其他問題和答案後,很明顯我需要我自己的JsonConverter。然而,我卡住的地方是我使用中間對象來處理數據,因爲它是(de)序列化的,並且由於根據筆刷類型存在各種類型的對象,我假設我需要將類型信息存儲在Json中,但是使用[JsonProperty(TypeNameHandling = TypeNameHandling.All)]不起作用。使用JsonConverter來序列化/反序列化各種'筆刷'類型

我的轉換器:

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

結束了去一個不同的路線,這是恕我直言,是一個執行更清潔。

保留過去是我的中間對象的對象,但它們現在是我實際存儲數據的對象,它們(爲了便於使用)繼承了基類;

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; 
    } 
} 

然後,而不是對象直接綁定到在XAML刷子,我創建了把我的自定義通用對象爲畫筆的轉換器(這是基類使事情變得非常簡單);存儲使用我的新類型所需要的刷信息

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(); 
    } 
} 

當然我的模板類,我還添加了OnDeserialized回調爲我的模板不會顯示如果我居住JSON的主窗口顯示後,

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" 
    } 
    } 
相關問題