Json 转换为双精度并绑定到 WPF nummericupdown 失败
Json conversion to double and bind to WPF nummericupdown fails
目前我在绑定时遇到错误。情况是我将设置写入 JSON 文件。当应用程序再次打开时,JSON 文件将在整个应用程序中被读取和使用。现在有一件奇怪的事情:当我将双精度值绑定到 nummericupdown 的值时,我得到一个错误:type 'JValue' to type 'System.Nullable1[System.Double]'for 'en-US'
但是当我重新创建 JSON 列表和文件时,这个错误不会发生。 (简单地说,当我删除文件并重新启动应用程序时,它将创建一个 class 的新实例并将其写入磁盘)
属性 在 class:
Public Property SomeValue As Double
Write/Reader JSON:
'Write
Using _file As StreamWriter = New StreamWriter(SettingFilePath)
Dim serializer As New JsonSerializer()
serializer.Formatting = Formatting.Indented
serializer.Serialize(_file, Me)
End Using
'Read
Return JsonConvert.DeserializeObject(Of Settings)(File.ReadAllText(settingsfile))
JSON 字符串:
"SomeValue": 1.0,
在 XAML 中绑定:
<Controls:NumericUpDown
Width="200"
HorizontalAlignment="Center"
Maximum="5"
Minimum="1"
NumericInputMode="All"
Speedup="false"
Value="{Binding SomeValue}" />
请注意,我使用的是 Mathapps Metro nummericupdown 控件版本 1.6.5
Newtonsoft 版本 10.0.0.1(由于依赖关系无法更新)
编辑:
按照要求我深入挖掘,现在知道它从哪里开始,但还不知道如何解决它。例如以我的 class 开头:
Public class Hello
Dim a as Object
Dim b as EnumTypeOfObjectIn_A
Dim SomeOtherStuff as String
End class
现在,当我 DeserializeObject
将文件删除到 Class Hello
时,变量 a
变成了 JObject
类型的对象,这就是为什么很多logica后记出错了。当我在代码中创建对象时,一切顺利,因为 TypeOf
对象与我输入的对象匹配。那么 Deserializer
是否有一个工作区将对象转换为变量中指示的对象b
?
找到了我正在寻找的解决方案。 Newtonsoft JSON
包含有助于 de/serialization 进程的 JsonSerializerSettings
class。对我来说,在序列化时添加对象类型很重要,这正是 TypeNameHandling
和 TypeNameAssemblyFormatHandling
在 Newtonsoft JSON
程序集
中的作用
我得到了这段代码:
Public Class Hello
Public Property A As Object
Dim settingsfile As String = "C:\jsontest.json"
Public Sub Save()
Using _file As StreamWriter = New StreamWriter(settingsfile)
_file.Write(JsonConvert.SerializeObject(Me, Formatting.Indented, New JsonSerializerSettings() With {
.TypeNameHandling = TypeNameHandling.Objects,
.TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple
}))
End Using
End Sub
Public Function Load() As Hello
Return JsonConvert.DeserializeObject(Of Hello)(File.ReadAllText(settingsfile), New JsonSerializerSettings() With {.TypeNameHandling = TypeNameHandling.Objects})
End Function
End Class
Public Class Person
Public Property Name As String
Public Property Age As Integer
Sub New()
Me.Name = "John"
Me.Age = 130
End Sub
End Class
生成这个 JSON 输出,注意 $Type
{
"$type": "MyNamespace.Hello, MyNamespace",
"A": {
"$type": "MyNamespace.Person, MyNamespace",
"Name": "John",
"Age": 130
}
}
目前我在绑定时遇到错误。情况是我将设置写入 JSON 文件。当应用程序再次打开时,JSON 文件将在整个应用程序中被读取和使用。现在有一件奇怪的事情:当我将双精度值绑定到 nummericupdown 的值时,我得到一个错误:type 'JValue' to type 'System.Nullable1[System.Double]'for 'en-US'
但是当我重新创建 JSON 列表和文件时,这个错误不会发生。 (简单地说,当我删除文件并重新启动应用程序时,它将创建一个 class 的新实例并将其写入磁盘)
属性 在 class:
Public Property SomeValue As Double
Write/Reader JSON:
'Write
Using _file As StreamWriter = New StreamWriter(SettingFilePath)
Dim serializer As New JsonSerializer()
serializer.Formatting = Formatting.Indented
serializer.Serialize(_file, Me)
End Using
'Read
Return JsonConvert.DeserializeObject(Of Settings)(File.ReadAllText(settingsfile))
JSON 字符串:
"SomeValue": 1.0,
在 XAML 中绑定:
<Controls:NumericUpDown
Width="200"
HorizontalAlignment="Center"
Maximum="5"
Minimum="1"
NumericInputMode="All"
Speedup="false"
Value="{Binding SomeValue}" />
请注意,我使用的是 Mathapps Metro nummericupdown 控件版本 1.6.5
Newtonsoft 版本 10.0.0.1(由于依赖关系无法更新)
编辑:
按照要求我深入挖掘,现在知道它从哪里开始,但还不知道如何解决它。例如以我的 class 开头:
Public class Hello
Dim a as Object
Dim b as EnumTypeOfObjectIn_A
Dim SomeOtherStuff as String
End class
现在,当我 DeserializeObject
将文件删除到 Class Hello
时,变量 a
变成了 JObject
类型的对象,这就是为什么很多logica后记出错了。当我在代码中创建对象时,一切顺利,因为 TypeOf
对象与我输入的对象匹配。那么 Deserializer
是否有一个工作区将对象转换为变量中指示的对象b
?
找到了我正在寻找的解决方案。 Newtonsoft JSON
包含有助于 de/serialization 进程的 JsonSerializerSettings
class。对我来说,在序列化时添加对象类型很重要,这正是 TypeNameHandling
和 TypeNameAssemblyFormatHandling
在 Newtonsoft JSON
程序集
我得到了这段代码:
Public Class Hello
Public Property A As Object
Dim settingsfile As String = "C:\jsontest.json"
Public Sub Save()
Using _file As StreamWriter = New StreamWriter(settingsfile)
_file.Write(JsonConvert.SerializeObject(Me, Formatting.Indented, New JsonSerializerSettings() With {
.TypeNameHandling = TypeNameHandling.Objects,
.TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple
}))
End Using
End Sub
Public Function Load() As Hello
Return JsonConvert.DeserializeObject(Of Hello)(File.ReadAllText(settingsfile), New JsonSerializerSettings() With {.TypeNameHandling = TypeNameHandling.Objects})
End Function
End Class
Public Class Person
Public Property Name As String
Public Property Age As Integer
Sub New()
Me.Name = "John"
Me.Age = 130
End Sub
End Class
生成这个 JSON 输出,注意 $Type
{
"$type": "MyNamespace.Hello, MyNamespace",
"A": {
"$type": "MyNamespace.Person, MyNamespace",
"Name": "John",
"Age": 130
}
}