Im just wondering how I go about saving an instance of a class to the silverlight isolated storage. I also need to know if it possible that the class that we save to isolated storage can have a list of instances of another class. Here is an example of the situation:
Public Class MySettingsToStore
private mPropertyA as string
Public Property PropertyA() As string
Get
Return mPropertyA
End Get
Set(ByVal value As string)
mPropertyA = value
End Set
End Property
private mlstOfSubClass as List(Of MySubClass)
Public Property lstOfSubClass() As List(Of MySubClass)
Get
Return mlstOfSubClass
End Get
Set(ByVal value As List(Of MySubClass))
mlstOfSubClass = value
End Set
End Property
End Class
Public Class MySubClass
private mPropertyA as string
Public Property PropertyA() As string
Get
Return mPropertyA
End Get
Set(ByVal value As string)
mPropertyA = value
End Set
End Property
private mPropertyB as string
Public Property PropertyB() As string
Get
Return mPropertyB
End Get
Set(ByVal value As string)
mPropertyB = value
End Set
End Property
End Class
So basically on load of the application I want to check if there is an instance of MySettingsToStore in the isolatedStorage if not I will create one and save it (and update it when needed), so the next time the application is started there will be an instance in the isolatedstorage to load.
Does anyone know how I go about this? Hope someone can help. Thanks in advance
One word: XMLSerializer
To elaborate a bit, you can serialize any class with public properties to a stream (e.g. in Isolated storage) and reverse that process on startup to load an existing file in ISO storage.
If a property is a collection of other classes, they too will be stored and restored by using XMLSerializer.
Related
I'm currently using Visual Basic for a College Project which requires us to make a simple database system. For my system I have a base(abstract) class called Record which is inherited by the different types of records there are in my database e.g. Member, User, Role.
I am saving my data in csv files and have already written a CSVHandler class. However, I want an elegant way of constructing an instance of a class derived from Record with a string from the CSVHandler.
This is where the problem occurs. The only way I can think of doing this is by making a Constrcutor or Shared Function in each class derived from Record. However, Visual Basic does not allow you make Constructors or Shared Functions also MustOverride.
Here is the code I would expect to write:
' Base Class
Public MustInherit Class Record
Public MustOverride Shared Function fromString(ByVal str as String) As Record
End Class
' Example Of Class Derived From Record
Public Class User
Inherits Record
Private _id As String
Private _name As String
Public Sub New(ByVal id As String, ByVal name As String)
_id = id
_name = name
End Sub
Public Overrides Shared Function fromString(ByVal str as String) As Record
Dim strs() As String = str.Split(",")
Return New User(strs(0), strs(1))
End Function
End Class
' Example Of Creating Instacnce Of User
Dim user1 = User.fromString("1671,Kappeh")
Is there a way to achieve this effect?
Have your constructor call a Protected MustOverride method that does the initialisation.
Public MustInherit Class Record
'This is required because each derived constructor must be able to implicitly invoke a parameterless
'base constructor if it doesn't explicitly invoke a base constructor with parameters.
Protected Sub New()
End Sub
Public Sub New(csv As String)
Init(csv)
End Sub
Protected MustOverride Sub Init(csv As String)
End Class
Public Class User
Inherits Record
Private Property Id As String
Private Property Name As String
'This is still required because you can use a base constructor directly to create a derived instance.
Public Sub New(csv As String)
MyBase.New(csv)
End Sub
Public Sub New(id As String, name As String)
Id = id
Name = name
End Sub
Protected Overrides Sub Init(csv As String)
'Add your type-specific implementation here.
End Sub
End Class
This "solution" doesn't actually do what I thought it would because, while it forces you to override Init in a derived class, you still have to provide a derived constructor that invokes the base constructor that calls Init and you still can't enforce that. I think that I'll leave this as an answer though, because, while it doesn't actually provide a solution to your problem, it demonstrates further why (as far as I can tell) there is no such solution.
The following is similar to the answer from #jmcilhinney in that it forces the derived class to implement an initialization method. However it makes use of a generic shared function and uses the little known GetUninitializedObject method to get around using the generic New constraint and it's requirement of an accessible parameter-less constructor.
Public MustInherit Class Record
Public Shared Function fromString(Of T As {Record})(ByVal str As String) As T
' create an unintialized instance of T
Dim ret As T = DirectCast(System.Runtime.Serialization.FormatterServices.GetUninitializedObject(GetType(T)), T)
ret.Initialize(str)
Return ret
End Function
Protected MustOverride Sub Initialize(source As String)
End Class
The User class then would be something like this:
Public Class User : Inherits Record
Private _id As String
Private _name As String
Public Sub New(ByVal id As String, ByVal name As String)
_id = id
_name = name
End Sub
Protected Overrides Sub Initialize(source As String)
Dim strs() As String = source.Split(","c)
_id = strs(0)
_name = strs(1)
End Sub
End Class
Example usage:
Dim userRecord As User = Record.fromString(Of User)("1,2")
some awesome dude put out the CS:GO skins data out as JSON.
http://api.ncla.me/data/data.json
But I am really struggling to deserialize it and access the individual items.
Could you guys help? Is it possible without third-party additions? ( I don't care how fast or slow it is. )
This is how far I have come
Public Class RootObject
Public Property ResultList_Main As List(Of ListWrapper_Main)
Public Class ListWrapper_Main
Public Property WeaponInfo As List(Of ListWrapper)
End Class
Public Class ListWrapper
Public Property value As String
Public Property quantity As String
End Class
End Class
jsonObject = jsSerializer.Deserialize(Of RootObject)(responseFromServer)
For Each Itemdetail1 In jsonObject.ResultList_Main
For Each Itemdetail2 In Itemdetail1.WeaponInfo
'Would like to display WeaponInfo + Value + Quantity here
Next
Next
I'm learning how to access data on a DB using a WCF web service. My main issue I've run into is that when making a call for the result from the service, the return value is of type UniversityClass but no properties are available and I believe its real type is simply an object, therefore I have no access to any of its 'real' properties.
Heres a snippet of the class in my interface called 'Service1'
<ServiceContract()>
Public Interface IService1
<OperationContract()>
Function GetUniversity(ByVal universityID As Integer) As UniversityClass
End Interface
<DataContract()>
Public Class UniversityClass
Private _universityId As Integer
Public Property UniversityID As Integer
Get
Return _universityId
End Get
Set(value As Integer)
_universityId = value
End Set
End Property
and heres a preview of me making the call to the service to get the data
Dim client As New ServiceReference1.Service1Client
Dim result As New ServiceReference1.UniversityClass
Dim x = client.GetUniversityAsync(Integer.Parse(tbUniversityID.Text))
Dim r As WCFServiceExample.ServiceReference1.UniversityClass = Await x
If x.IsCompleted Then
result = x.Result
End If
tbResult.Text = result. _ _ _ _
'// ^ No properties accessible here even though it recognizes that result is of type UniversityClass
Upon inspecting ServiceReference1.UniversityClass I get taken to Referece.vb and notice that there is Partial Class UniversityClass which inherits object. I think perhaps that may be the reason why I don't have any access to the properties defined in my Service1 class because it thinks UniversityClass is an object with no type.
I've tried rebuilding all projects individually, rebuilding the solution and still nothing.
Would love some assistance with how to actually get an object of type UniversityClass to return from my service.
Recognizes the type: http://i50.tinypic.com/e5mhvk.jpg
No properties available: http://i50.tinypic.com/wmjui9.jpg
Any help would be greatly greatly appreciated!
Your client can't see the UniversityID because you haven't marked it as a data member:
<DataContract()>
Public Class UniversityClass
Private _universityId As Integer
<DataMember()>
Public Property UniversityID As Integer
Get
Return _universityId
End Get
Set(value As Integer)
_universityId = value
End Set
End Property
I have some code that works in winforms, but not in WPF apparently, the code is as follows:
This is set globally:
Private Property avar As Object
Public main As MainWindow
Public charchoice As Char
And then in the Window Loaded sub, this is placed:
charchoice = main.charchoice
Thing is, the next window doesn't pick up this variable, so how can I make it recognise and use it? Thanks Guys
Nick
I had a similar problem and discovered that you must create a public property in the MainWindow and pass a value to the property.
Please see this example from a similar question I posted.
Hey i got same problem when i am going to pass values between two forms.
I find its solution using a simple class and Shared property.
First I create a class named with cls_pass_val which is as under:-
Public Class cls_pass_val
Private Shared var_pass_val As String = ""
Public Shared Property Pass_val() As Char
Get
Return var_pass_val
End Get
Set(ByVal value As String)
var_pass_val = value
End Set
End Property
End Class
Now at the time of assigning a value:
cls_pass_val.Pass_val='A'
and at the time of retrieving the value:
Dim var_c as Char
var_c=cls_pass_val.Pass_val
Ok - I'm pulling my hair out over what I thought was a simple scenario: create a custom Label for bilingual use that contained two additional properties (EnglishText, FrenchText). Currently its structured like this:
Public Class myCustomLabel
Inherits System.Windows.Controls.Label
Public myEnglishTextProperty As DependencyProperty = DependencyProperty.Register("myEnglishText", GetType(String), GetType(myCustomLabel), New PropertyMetadata("English", New PropertyChangedCallback(AddressOf TextChanged)))
Public myFrenchTextProperty As DependencyProperty = DependencyProperty.Register("myFrenchText", GetType(String), GetType(myCustomLabel), New PropertyMetadata("Francais", New PropertyChangedCallback(AddressOf TextChanged)))
Public Sub New()
'This OverrideMetadata call tells the system that this element wants to provide a style that is different than its base class.
'This style is defined in themes\generic.xaml
DefaultStyleKeyProperty.OverrideMetadata(GetType(myCustomLabel), New FrameworkPropertyMetadata(GetType(myCustomLabel)))
End Sub
Public Property myEnglishText() As String
Get
Return MyBase.GetValue(myFrenchTextProperty)
End Get
Set(ByVal value As String)
MyBase.SetValue(myFrenchTextProperty, value)
End Set
End Property
Public Property myFrenchText() As String
Get
Return MyBase.GetValue(myFrenchTextProperty)
End Get
Set(ByVal value As String)
MyBase.SetValue(myFrenchTextProperty, value)
End Set
End Property
Private Sub TextChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
If DesignerProperties.GetIsInDesignMode(Me) = True Then
Me.Content = myEnglishText
Else
If myUser.Language = "E" Then
Me.Content = myEnglishText
Else
Me.Content = myFrenchText
End If
End If
End Sub
End Class
My test window grid xaml is simple:
<Grid>
<my:myCustomLabel myEnglishText="English Text" myFrenchText="English Text" Height="25" Width="100" Background="Aqua" Foreground="Black"/>
</Grid>
This seems to work in the development environment - changing the English and French texts change the in the design preview and it works when the app runs and the test window is opened. But only the first time - if I open the test window a second time I receive the following message:
'myEnglishText' property was already
registered by 'myCustomLabel'.
I understand now that if I change the dependency property declarations to shared then this problem goes away - but that leads to a host of other problems like the callback function being required to be shared as well - and thus unable to update the Content (which needs to be instantiated with the class). All I really want is the content property to be updated in design time when the english and french labels are changed.
Is there a way around this? Or maybe are dependency properties overkill for what I need?
You are registering your dependency properties as instance variables, and during the instance constructor. So they are getting registered again every time you instantiate the control, which causes an error the second time. As you have found out, dependency properties need to be static (Shared) members:
Public Shared myEnglishTextProperty As DependencyProperty =
DependencyProperty.Register("myEnglishText", GetType(String), GetType(myCustomLabel),
New PropertyMetadata("English", New PropertyChangedCallback(AddressOf TextChanged)))
You probably need to call OverrideMetadata in your shared constructor (type initialiser) rather than your instance constructor as well.
Regarding your issue with the callback needing to be shared: yes, it will be, but one of the arguments to the callback is the label instance. So you can just cast that to label and call an instance method on that:
private static void TextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((MyLabel)d).TextChanged();
}
private void TextChanged()
{
// your code here
}
(forgive C# syntax)
Is the reason you don't want the callback method to be shared because you're accessing the "me" instance? If that's all it is, make it shared and use the "d" parameter. I don't know VB well enough to show you the code, but just create a variable of type myCustomLabel and assign "d" to it (with a cast). Then use that variable (say "lbl") instead:
If DesignerProperties.GetIsInDesignMode(lbl) = True Then
lbl.Content = myEnglishText
Else
If myUser.Language = "E" Then
lbl.Content = myEnglishText
Else
lbl.Content = myFrenchText
End If
End If
Also, there's a slight bug in your example code. Try using this:
Public Property myEnglishText() As String
Get
Return MyBase.GetValue(myEnglishTextProperty)
End Get
Set(ByVal value As String)
MyBase.SetValue(myEnglishTextProperty, value)
End Set
End Property
Instead of this:
Public Property myEnglishText() As String
Get
Return MyBase.GetValue(myFrenchTextProperty)
End Get
Set(ByVal value As String)
MyBase.SetValue(myFrenchTextProperty, value)
End Set
End Property