- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
因此,在阅读了有关 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/
我正在尝试使用链接到 map 的 d3.js 创建垂直时间轴,以便画笔中包含的任何项目也将显示在 map 中。有点像http://code.google.com/p/timemap/但使用 d3 而不
我正在通过另一个类的反射检索画笔列表。我想确保此列表中的某些画笔不是透明的 (#00FFFFFF)。但是,将它与 Brushes.Transparent 进行比较会返回 false,即使该值实际上是
我有 2 个问题想用我当前基于 this 的 d3 应用程序修复: 这是 fiddle :http://jsfiddle.net/zoa5m20z/ 我想初始化我的笔刷,以便在应用程序启动时默认只刷一
我正在构建一个画笔应用程序,它快完成了,我所做的只是一个基本的画笔/绘图工具。我想给它一种更像画笔的感觉,因为在我当前的输出中它有角度并且看起来不像真正的画笔墨水。 这是我的代码: - (void)t
我正在尝试为文本框添加水印。 TextBox.Background 是一个 System.Windows.Media.Brush。我需要 Graphics.FillRectangle(System.D
如何将 System.Windows.Media.Brush 转换为 System.Drawing.Brush? 我正在尝试将 system.windows.media.brush 的颜色格式化为 S
如何或什么是最好的序列化方法 System.Windows.Media.Brush ? 最佳答案 这里有一个关于如何序列化 WPF 的很好的讨论: http://statestreetgang.net
我将IEnumerable用作ItemsSource的ComboBox遇到此问题;问题出在我(以编程方式)尝试设置SelectedItem时。这是描述问题的代码: private readonly L
docs直接进入使用“画笔”API 的详细信息,而无需描述“画笔”是什么。 当然,我可以根据该页面中给出的示例做出自己有根据的猜测,但我正在寻找有关“画笔”是什么的更正式的介绍。 (搜索“画笔”,甚至
我目前有以下方法 public void printTitle(string title){ // settings for stringformat g.DrawString(tit
我正在编写一个基于 Mike Bostocks 示例的 d3 小部件 http://bl.ocks.org/mbostock/1667367因此,我尝试使用预定义日期设置画笔范围,但范围矩形不适用于这
我有一个属性允许将已知颜色的字符串名称发送到我的控件。该属性只接受正确的已知颜色名称,如“红色”或“蓝色” private KnownColor _UseColor = KnownColor.Re
在 Paint 事件中使用新的 Brush 是不是更好的方法,即 protected override void OnPaint(PaintEventArgs e) { e.Graphics.
下面是康威生命游戏在 WPF 中的一个(非常幼稚的)实现。这只是一个演示... xaml: 代码隐藏: using System; usin
这个问题在这里已经有了答案: Convert string to Brushes/Brush color name in C# (10 个答案) 关闭 5 年前。 我有一个矩形,我想用一种颜色填充它
我需要将一些颜色(十六进制)转换为 Brush。 我需要在代码中做到这一点。 我该怎么做 ? 最佳答案 //this would be initialized somewhere else, I as
我花了大约一周的时间阅读所有关于 iPhone 绘图、动画和 OpenGL 的免费信息。使用可用的 iOS 绘图示例(例如 Apple 的 GLPaint 和 Quartz 示例应用程序),我编写了几
我一直在通过使用 Brush & Zoom 来学习 d3制作自定义时间线的示例。我希望能够允许用户保存时间线的“ View ”:缩放和平移到特定点,将它们保存到 JSON 中,然后稍后恢复它们。 任何
我想知道如何更好地控制我的 d3.brush 组件。我想对其进行一些额外的控制,例如: 右键单击(打开一个特殊菜单,而不是常规的浏览器菜单 - 也不是奇怪的画笔行为) 能够禁用可调整大小(即允许用户仅
Windows.Media.Brush 不是可序列化的类,所以我想知道如何序列化它。 我将 [Serializable] 属性放在类本身上,将 [DataContract] 和 [DataMember
我是一名优秀的程序员,十分优秀!