I have made a simple Class to save user settings. All is working well but I'd like to simplify/generalize a little more, but I am having trouble getting the Object (TestSavedSettings) from it's Property (FormLocation). As seen in the code below I am able to get the Form1 object from it's Location Property... but I can't get it to work the same for the TestSavedSettings.FormLocation.
The code below is complete and can be cut pasted into a new VB Windows Forms Application and run, it will persist the forms location for each start up.
Bottom line: How can I get the Object that is for the TestSettings.AddBinding 'sn' argument? (just as I am doing successfully for the 'pn' argument?
Imports System.Linq.Expressions
Imports System.Configuration
Imports System.Reflection
Public Class Form1
Private TestSavedSettings As New TestSettings_TestForm
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
TestSavedSettings.AddBinding(Function() Me.Location, Function() TestSavedSettings.FormLocation)
'Below is what I would like to use instead of the version in the line above
' TestSettings.AddBinding(Function() Me.Location, Function() TestSavedSettings.FormLocation)
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
TestSavedSettings.Save()
End Sub
End Class
Public Class TestSettings_TestForm : Inherits ApplicationSettingsBase
<UserScopedSettingAttribute()>
Public Property FormLocation() As Point
Get
Return CType(Me(MethodBase.GetCurrentMethod().Name.Remove(0, 4)), Point)
End Get
Set(ByVal value As Point)
Me(MethodBase.GetCurrentMethod().Name.Remove(0, 4)) = value
End Set
End Property
'--This alternative method works, but I'd like to just have one shared version of this in a seperate Class as shown at end
Public Sub AddBinding(Of T, T2)(ByVal pn As Expression(Of Func(Of T)), ByVal sn As Expression(Of Func(Of T2)))
Dim FrmPropertyName As String = DirectCast(pn.Body, MemberExpression).Member.Name
Dim Frm As Form = DirectCast(DirectCast(DirectCast(pn.Body, MemberExpression).Expression, ConstantExpression).Value, Form)
Dim SettingName As String = DirectCast(sn.Body, MemberExpression).Member.Name
Frm.DataBindings.Add(New Binding(FrmPropertyName, Me, SettingName, True, DataSourceUpdateMode.OnPropertyChanged))
End Sub
End Class
Public Class TestSettings
Public Shared Sub AddBinding(Of T, T2)(ByVal pn As Expression(Of Func(Of T)), ByVal sn As Expression(Of Func(Of T2)))
Dim FrmPropertyName As String = DirectCast(pn.Body, MemberExpression).Member.Name
Dim Frm As Form = DirectCast(DirectCast(DirectCast(pn.Body, MemberExpression).Expression, ConstantExpression).Value, Form)
Dim SettingName As String = DirectCast(sn.Body, MemberExpression).Member.Name
'>>>>>Problem is with line below, causes exception, .Expression is actrually returning a FieldExpression not a ConstantExpression,
'but can't cast to that....
Dim Setting As Object = DirectCast(DirectCast(sn.Body, MemberExpression).Expression, ConstantExpression).Value
Frm.DataBindings.Add(New Binding(FrmPropertyName, Setting, SettingName, True, DataSourceUpdateMode.OnPropertyChanged))
End Sub :End Class
One way to do what you want would be to to compile and execute the sub-expression that contains the value that you need, instead of trying to process it manually:
Dim settingExpression = DirectCast(sn.Body, MemberExpression).Expression
Dim setting = Expression.Lambda(Of Func(Of Object))(settingExpression).Compile().Invoke()