Xojo 2019 で control set を作ってコントロールを配列で扱うようにする方法と注意点

コントロールを並べる時に、配列で扱う方法についての備忘録。


# 環境

- Windows 10 Pro
- Xojo 2019 Release 3.2
- Desktop アプリと Web アプリで検証


なお、最近の Xojo は以下のようにおこなうようです。
https://blog.xojo.com/2022/01/21/simplified-adding-user-interface-controls-at-runtime/

# 作り方

TextField の配列を作る場合を例にして説明します。

「TextFieldテスト」という名前のTextFieldを作ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/037f6a62-dff5-e8ec-d338-ed3dee52bbe6.png)

TextField を必要なだけ並べます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/97749f58-911b-73b0-f457-c8f50de1b878.png)

2つ目の TextField の名前を1つ目と同じ「TextFieldテスト」にすると、「control  set」にするかどうか聞いてくるので「OK」を押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a1c2e673-8f8e-f01b-4e24-e69846bbb9bd.png)

3つ目以降も同様にして、「TextFieldテスト(0)」〜「TextFieldテスト(4)」を作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/917a620a-8010-0bd9-ca60-140294741e21.png)

# 使い方

## Desktop アプリ


ここでは PushButton を押す Action で control set を扱ってみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/332b55e0-2540-b822-6ae0-e4b00f0e3a82.png)

PushButton の Action に、以下を記述します。
```
var i as integer = 0
while TextFieldテスト(i)<>nil
  TextFieldテスト(i).Value =i.ToString
  i=i+1
wend
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/6bf91f71-8df0-e01d-4701-805161dedfd2.png)

ボタンを押すと、ControlSet でアクセスした TextField に値が入ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/954aed94-2af6-63bc-65e2-f27c90e729dc.png)


## Webアプリ
ほぼ同じです。


```
var i as integer = 0
while TextFieldテスト(i)<>nil
  TextFieldテスト(i).Text =i.ToString
  i=i+1
wend
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/10e2941d-4ae8-d235-00d9-992fdab67a26.png)


# 注意点


- この記事では「配列」として扱っているが、本当の配列ではないらしい
- なので配列の UBound や ListCount などを得ることはできない

先のサンプルコードでは `For ~ Next` の係数を決め打ちで回していたが、配列上限をチェックするには以下のようにする


```
var i as integer = 0
while TextFieldテスト(i)<>nil
  TextFieldテスト(i).Value =i.ToString
  i=i+1
wend

```

# Controlを増やす

## デスクトップ

```
Var newTF,newTF2 As TextField
var Count as integer = 0

while TextFieldテスト(Count)<>nil
  Count=Count+1
wend

newTF = New TextFieldテスト

newTF.Top = TextFieldテスト(Count-1).Top + 34
newTF.Left = TextFieldテスト(Count-1).Left
newTF.Width = TextFieldテスト(Count-1).Width
newTF.Height = TextFieldテスト(Count-1).Height
newTF.Visible = TextFieldテスト(Count-1).Visible
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/bdff96d6-13f3-bc42-e12a-12edac881243.png)

プロパティを丸々コピーするのは以下にヒントがありますがうまくいかず、上のようにひとつひとつ設定しました。

https://blog.xojo.com/2018/01/26/how-to-add-ui-controls-at-runtime/

## Web 

以下のようにしてみたが、うまくいきません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/40a0890b-df0d-9f5e-814c-945a6164d5fe.png)
 https://blog.xojo.com/2022/01/21/simplified-adding-user-interface-controls-at-runtime/
```
Sub Action()
  Var newTF As WebTextField
  var Count as integer = 0
  
  while TextFieldテスト(Count)<>nil
    Count=Count+1
  wend
  
  newTF = New TextFieldテスト
  
  newTF.Top = TextFieldテスト(Count-1).Top + 34
  newTF.Left = TextFieldテスト(Count-1).Left
  newTF.Width = TextFieldテスト(Count-1).Width
  newTF.Height = TextFieldテスト(Count-1).Height
  newTF.Visible = TextFieldテスト(Count-1).Visible
End Sub
```

どうやら Web1.0 では、コントロールをダイナミックに増減するには WebContainer を使う必要があるようです。

https://forum.xojo.com/t/control-sets-on-web-page/22186/11

http://man.hubwiz.com/docset/Xojo.docset/Contents/Resources/Documents/docs.xojo.com/UserGuide_Web_Control_Sets.html

http://man.hubwiz.com/docset/Xojo.docset/Contents/Resources/Documents/docs.xojo.com/UserGuide_Web_Container_Control.html

## Web1.0 でコントロールをダイナミックに増減するには

実用的には、十分な数のコントロールを配列にセットしておき、 Visible を True/False に操作するのが良さそう。