How to use dotNet .GetProperty() with BindingFlags

How to use dotNet .GetProperty() with BindingFlags

akarcode
Participant Participant
1,010 Views
4 Replies
Message 1 of 5

How to use dotNet .GetProperty() with BindingFlags

akarcode
Participant
Participant

I'm trying to access by default protected dotNet Properties. I can't figure out how to use .GetProperty() with BindingFlags.

This is my current function:

 

fn doubleBuffered dgv args = (

--.<System.Type>GetType()
dgvType = dgv.GetType()

--.<System.Reflection.PropertyInfo>GetProperty <System.String>name
propertyReadOnly = dgvType.GetProperty("ReadOnly")

--.<System.Object>GetValue <System.Object>obj
propertyReadOnly.GetValue(dgv)
-- this works!



--.<System.Reflection.PropertyInfo>GetProperty <System.String>name <System.Reflection.BindingFlags>bindingAttr
flagInstance = (dotNetClass "System.Reflection.BindingFlags").Instance
flagNonPublic = (dotNetClass "System.Reflection.BindingFlags").NonPublic
propertyReadOnly = dgvType.GetProperty("DoubleBuffered" flagInstance or flagNonPublic)
-- Type error: Call needs function or class, got: "DoubleBuffered"

--next step
--.SetValue <System.Object>obj <System.Object>value
--.SetValue <System.Object>obj <System.Object>value <System.Object[]>index
--.SetValue <System.Object>obj <System.Object>value <System.Reflection.BindingFlags>invokeAttr <System.Reflection.Binder>binder <System.Object[]>index <System.Globalization.CultureInfo>culture

)

doubleBuffered dataGrid false

 

 
It seems that any additional property in .GetProperty() breaks the code.

Here is a sample code to try this with:

 

global doubleBufferForm (
	
	if doubleBufferForm != undefined do doubleBufferForm.close()
	
	pointClass = dotNetClass "System.Drawing.Point"
	sizeClass = dotNetClass "System.Drawing.Size"
	colorClass = (dotNetClass "System.Drawing.Color").fromARGB
	
	doubleBufferForm = dotNetObject "maxCustomControls.MaxForm"
	doubleBufferForm.Text = "DoubleBuffer Test"
	doubleBufferForm.Size = dotNetObject sizeClass 900 600
	doubleBufferForm.StartPosition = (dotNetClass "System.Windows.Forms.FormStartPosition").CenterScreen

	borderPanel = dotnetobject "Panel"
	borderPanel.Location = dotNetObject pointClass 5 5
	borderPanel.Size = dotNetObject sizeClass 868 535
	borderPanel.Anchor = dotNet.CombineEnums borderPanel.Anchor.Top borderPanel.Anchor.Bottom borderPanel.Anchor.Left borderPanel.Anchor.Right
	borderPanel.Padding = dotNetObject "System.Windows.Forms.Padding" 1
	doubleBufferForm.Controls.Add borderPanel
	
	dataGrid = dotNetObject "DataGridView"
	dataGrid.BorderStyle = dataGrid.BorderStyle.None
	dataGrid.Dock = dataGrid.Dock.Fill
	dataGrid.RowHeadersVisible = false
	dataGrid.AutoSizeColumnsMode = dataGrid.AutoSizeColumnsMode.Fill
	dataGrid.AllowUserToResizeRows = false
	dataGrid.AllowUserToResizeColumns = true
	dataGrid.AllowUserToOrderColumns = true
	dataGrid.AllowUserToAddRows = false
	dataGrid.ColumnHeadersHeight = 34
	dataGrid.ColumnHeadersHeightSizeMode = dataGrid.ColumnHeadersHeightSizeMode.DisableResizing
	dataGrid.BackgroundColor = colorClass 255 255 255
	dataGrid.ForeColor = colorClass 0 0 0
	dataGrid.ShowEditingIcon = false
	dataGrid.ReadOnly = true
	dataGrid.SelectionMode = dataGrid.SelectionMode.FullRowSelect
	
	allColumnNames = #("First", "Second", "Third")
	for columnName in allColumnNames do (
		
		Column = dotNetObject "DataGridViewTextBoxColumn"
		Column.HeaderText = columnName
		
		dataGrid.Columns.Add Column
		
	)
	
	for _ = 1 to 1000 do (
		
		newRow = dotnetobject "DataGridViewRow"
		dataGrid.Rows.Add newRow
		
		newRow.Cells.Item[0].Value = (substring (genguid()) 2 36)
		newRow.Cells.Item[1].Value = (substring (genguid()) 2 36)
		newRow.Cells.Item[2].Value = (substring (genguid()) 2 36)
			
	)
	
	borderPanel.Controls.Add dataGrid
	
	doubleBufferForm.showModeless()

)​

 

Thanks for any pointers on this.
0 Likes
Accepted solutions (1)
1,011 Views
4 Replies
Replies (4)
Message 2 of 5

denisT.MaxDoctor
Advisor
Advisor
Accepted solution

 

form = dotnetobject "Form"
type = form.GetType()

binding_flags = dotnetclass "System.Reflection.BindingFlags"
flags = dotnet.combineenums binding_flags.Instance binding_flags.NonPublic
prop = type.GetProperty "DoubleBuffered" flags

 

0 Likes
Message 3 of 5

akarcode
Participant
Participant

Brilliant, it works as expected now. Those () really trolled me hard on this one 😅

Than you very much 🙏

0 Likes
Message 4 of 5

denisT.MaxDoctor
Advisor
Advisor

Just to better understand what dotnet.combineenums does :

 

_flags = dotnetclass "System.Reflection.BindingFlags"
_convert = dotnetclass "System.Convert" 

f1 = _convert.ToUInt64 _flags.Instance
f2 = _convert.ToUInt64 _flags.NonPublic
ff = _flags.ToObject _flags (f1 + f2)

 

 

0 Likes
Message 5 of 5

akarcode
Participant
Participant

That is some nice additional tech info.

Also here is the documentation link: https://help.autodesk.com/view/MAXDEV/2022/ENU/?guid=GUID-9BE82D70-1869-46D7-9501-E5453E25AC68
Towards the bottom is 'Enums' information and a usage example.

It's also interesting how the BindingFlags are applied totally different depending on the Programming language.

Thanks again.

0 Likes