gpt4 book ai didi

c# - 使用 JsonConverter 序列化/反序列化各种 `Brush` 类型

转载 作者:太空宇宙 更新时间:2023-11-03 12:28:16 25 4
gpt4 key购买 nike

因此,在阅读了有关 Json.NET 无法(反)序列化 Brush 类型的各种其他问题和答案后,很明显我需要自己的 JsonConverter。然而,我被卡住的地方是我正在使用中间对象来处理数据,因为它是(反)序列化的,并且由于根据画笔类型有各种类型的对象,我假设我也需要将类型信息存储在 Json 中,但是使用 [JsonProperty( TypeNameHandling = TypeNameHandling.All )] 不起作用。

我的转换器:

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 中,并将各种画笔设置为颜色、图像或渐变(尚未包括在内)。

最佳答案

最终选择了不同的路线,恕我直言,这种实现方式更加简洁。

保留了曾经是我的中介对象的对象,但它们现在是我实际使用的存储数据的对象,并且它们(为了便于使用)继承了一个基类;

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

然后,我没有将对象直接绑定(bind)到 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"
}
}

关于c# - 使用 JsonConverter 序列化/反序列化各种 `Brush` 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43761621/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com