Используйте основанные на флаге .NET перечисления из Lua - PullRequest
3 голосов
/ 17 февраля 2012

Я использую LuaInterface для .NET для создания объектов Windows Forms. Это работает довольно хорошо, за исключением одного:

Я хочу использовать Anchor свойство Control для автоматического изменения их размера. Если я установлю только один из якорей (например, только AnchorStyles.Top), он будет работать, но это не имеет смысла. Я должен установить более одного якоря, что делается путем объединения их с «побитовым или» (или просто добавляя их численно).

В VB.Net оба работают:

Dim myLabel As New Label()
myLabel.Anchor = AnchorStyles.Top
myLabel.Anchor = AnchorStyles.Top + AnchorStyles.Left + _
                 AnchorStyles.Bottom + AnchorStyles.Right

В Lua это работает:

luanet.load_assembly("System.Windows.Forms")
local WinForms = luanet.System.Windows.Forms
local myLabel = WinForms.Label()
myLabel.Anchor = WinForms.AnchorStyles.Top

... но этой дополнительной строки нет:

myLabel.Anchor = WinForms.AnchorStyles.Top + WinForms.AnchorStyles.Left + 
               WinForms.AnchorStyles.Bottom + WinForms.AnchorStyles.Right

Это дает мне следующую ошибку:

LuaInterface.LuaException: attempt to perform arithmetic on
field 'Top' (a userdata value)

, что в некотором смысле правильно, поскольку «LuaInterface рассматривает значения перечисления как поля соответствующего типа перечисления» (говорит LuaInterface: Скрипт .NET CLR с Lua ).


Также невозможно присвоить значение в виде числа:

myLabel.Anchor = 15    -- 15 = 8 + 4 + 2 + 1 = Top+Left+Right+Bottom

На этот раз сообщение об ошибке довольно неопределенное:

LuaInterface.LuaException: function

Как я могу обойти это?

Есть ли возможность типизировать число к правильному типу перечисления в Lua ?

1 Ответ

1 голос
/ 24 февраля 2012

Я наконец-то понял, как это сделать. Я использовал ToObject метод System.Enum. Он принимает тип перечисления, в которое я хочу преобразовать его, и целочисленное значение для использования.

Ниже приведен фрагмент кода из моей вспомогательной библиотеки:

local EnumToObject, WinFormsAnchorStylesType = 
                luanet.get_method_bysig(luanet.System.Enum, "ToObject",
                                             "System.Type", "System.Int32"),
                luanet.System.Windows.Forms.AnchorStyles.Top:GetType()

AnchorTop, AnchorLeft, AnchorRight, AnchorBottom = 1, 4, 8, 2

function Anchor(flags)
  return EnumToObject(WinFormsAnchorStylesType, flags)
end

Вы используете это так:

Label1 = luanet.System.Windows.Forms.Label()
Label1.Anchor = Anchor(AnchorLeft + AnchorTop + AnchorRight + AnchorBottom)
...