Langkau tajuk talian

Kawalan

Kawalan membolehkan interaksi tertentu yang melibatkan cBot, indikator dan plugin. Menggunakan panduan di bawah, anda boleh dengan mudah mencipta kawalan UI asas dan lanjutan secara langsung pada carta.

Terdapat beberapa kelas terbina dalam yang mewakili kawalan popular seperti butang, blok teks, kotak teks dan bentuk. Walau bagaimanapun, anda juga boleh mencipta kawalan tersuai.

Pertimbangkan contoh berikut:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
using cAlgo.API;

namespace ChartControlsTest
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class ChartControls : Indicator
    {
        [Parameter(DefaultValue = "Click Me")]
        public string Text { get; set; }

        [Parameter(DefaultValue = HorizontalAlignment.Center)]
        public HorizontalAlignment HorizontalAlignment { get; set; }

        [Parameter(DefaultValue = VerticalAlignment.Center)]
        public VerticalAlignment VerticalAlignment { get; set; }

        protected override void Initialize()
        {
            var button = new Button
            {
                Text = Text,
                HorizontalAlignment = HorizontalAlignment,
                VerticalAlignment = VerticalAlignment
            };

            button.Click += Button_Click;

            Chart.AddControl(button);
        }

        private void Button_Click(ButtonClickEventArgs obj)
        {
            obj.Button.Text = "You clicked me, thanks";
        }

        public override void Calculate(int index)
        {
        }
    }
}

Jika anda membina indikator di atas dan mencipta satu contoh, anda sepatutnya melihat butang kelabu Klik saya tepat di tengah-tengah carta.

Perbezaan antara kawalan dan objek carta

Dalam bahagian sebelumnya, kita telah membincangkan objek carta. Kawalan membolehkan pengguna berinteraksi dengan cBot dan indikator. Sebaliknya, objek carta memberi peluang untuk melukis sesuatu pada carta dagangan atau dalam tetingkap output indikator yang berasingan.

Kawalan carta berasal daripada kelas ControlBase manakala objek carta berasal daripada kelas ChartObject.

Kawalan carta diletakkan secara statik dengan menggunakan pilihan penjajaran yang berbeza. Walaupun objek carta boleh diletakkan dengan cara yang sama, kedudukan mereka juga boleh berubah secara dinamik bergantung pada koordinat X dan Y tertentu.

Sama seperti objek carta, kawalan carta boleh ditambah pada carta utama dan mana-mana tetingkap output indikator (jika ada). Contoh peletakan sedemikian diberikan di bawah:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
using cAlgo.API;

namespace ChartControlsTest
{
    [Indicator(IsOverlay = false, AccessRights = AccessRights.None)]
    public class ChartControls : Indicator
    {
        [Parameter(DefaultValue = "Click Me")]
        public string Text { get; set; }

        [Parameter(DefaultValue = HorizontalAlignment.Center)]
        public HorizontalAlignment HorizontalAlignment { get; set; }

        [Parameter(DefaultValue = VerticalAlignment.Center)]
        public VerticalAlignment VerticalAlignment { get; set; }

        protected override void Initialize()
        {
            var button = new Button
            {
                Text = Text,
                HorizontalAlignment = HorizontalAlignment,
                VerticalAlignment = VerticalAlignment
            };

            button.Click += Button_Click;

            IndicatorArea.AddControl(button);
        }

        private void Button_Click(ButtonClickEventArgs obj)
        {
            obj.Button.Text = "You clicked me, thanks";
        }

        public override void Calculate(int index)
        {
        }
    }
}

Selepas mencipta contoh indikator, anda sepatutnya melihat butang Klik saya dalam tetingkap output indikator.

ColorPicker

Kawalan ColorPicker membolehkan pedagang memilih warna pilihan mereka untuk elemen atau objek utama dalam cTrader. Sebagai contoh, pembangun boleh mengintegrasikan kawalan ColorPicker ke dalam cBot yang melukis garis trend supaya pengguna boleh memilih warna pilihan mereka untuk setiap garis trend. Persediaan ini memudahkan pedagang untuk membezakan antara pelbagai jenis garis trend.

Plugin yang menambah indikator pada carta juga boleh melaksanakan kawalan ColorPicker kerana ciri ini membolehkan pengguna memilih warna untuk garis indikator yang berbeza.

Apabila pengguna mengklik petak warna, pemilih warna akan muncul. Pengguna kemudian boleh memilih antara warna standard dan tersuai.

Sampel kod:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using System;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Plugins
{
    [Plugin(AccessRights = AccessRights.None)]
    public class ColorPickerTest : Plugin
    {
        protected override void OnStart()
        {
            var aspBlock = Asp.SymbolTab.AddBlock("Color Picker");

            var colorPicker = new ColorPicker {IsStretched = true, SelectedColor = Color.Red, Height = 20, Width = 20, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center};

            aspBlock.Child = colorPicker;

            colorPicker.SelectedColorChanged += colorPicker_SelectedColorChanged;

        }

        private void colorPicker_SelectedColorChanged(ColorPickerSelectedColorChangedEventArgs obj)
        {
            Print($"colorPicker_SelectedColorChanged, NewSelectedColor: {obj.NewSelectedColor} | PreviousSelectedColor: {obj.PreviousSelectedColor}");
        }

        protected override void OnStop()
        {
            // Handle Plugin stop here
        }
    }        
}

Image title

DropZone

Kawalan DropZone membolehkan pedagang melakukan tindakan seret dan lepas yang melibatkan cBot, indikator atau plugin. Untuk melaksanakan kawalan ini dalam algoritma anda, gunakan kelas DropZone. Kawalan DropZone boleh dimanipulasi seperti kawalan lain.

Apabila pengguna menjatuhkan fail atau folder yang serasi ke dalam kotak, peristiwa Dropped akan dijana. Apabila pengguna menjatuhkan folder atau beberapa folder ke dalam kotak, hanya fail yang serasi dengan sambungan yang dinyatakan dalam FilterExtensions akan diproses dan disalin.

Nota

Fail yang dijatuhkan biasanya disalin dan disimpan di lokasi ini: ..\Documents\cAlgo\Data\{AlgoType}\{AlgoName}\Selected Files\

Lokasi untuk contoh cBot berbeza daripada yang di atas: ..\Documents\cAlgo\Data\cBots\{cBotName}\{unique-instance-number}\Selected files\

Kod plugin ini menunjukkan kepada anda cara untuk menambah kawalan DropZone ke Trade Watch:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
using System;
using System.Drawing;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Plugins
{
    [Plugin(AccessRights = AccessRights.None)]
    public class TradeWatchTabSample : Plugin
    {
        protected override void OnStart()
        {
            var tab = TradeWatch.AddTab("DropZone");

            var _border = new Border
            {
                BorderThickness = 3,
                BorderColor = Color.DarkGray,
                Opacity = 0.7,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                Height = 200,
                Width = 350,
                BackgroundColor = Color.LightGray
            };

            var _textBlock = new TextBlock
            {
                Text = "Drag your files here",
                Opacity = 1,
                ForegroundColor = Color.DarkGray,
                FontSize = 16,
                VerticalAlignment = VerticalAlignment.Center,
                HorizontalAlignment = HorizontalAlignment.Center
            };

            var _dropzone = new DropZone
            {
                FilterExtensions = new string[] { "txt", "algo", "csv" },
                IsDirectoryDropAllowed = true,
                IsVisible = true,
                IsEnabled = true
            };
            _border.Child = _textBlock;
            _dropzone.Child = _border;
            //   _dropzone.Child = _textBlock;
            tab.Child = _dropzone;

            _dropzone.Dropped += Dropped_file;
        }

        private void Dropped_file(DroppedEventArgs obj)
        {
            Print("File has been added!");
        }
    }
}

Image title

ProgressBar

Kawalan ProgressBar memaparkan kemajuan operasi yang sedang berlangsung. Bar kemajuan menjadikan algoritma lebih mesra pengguna dan membantu menguruskan jangkaan pedagang mengenai masa menunggu untuk operasi tertentu.

API cTrader Algo membolehkan pembangun menambah dua jenis kawalan ProgressBar: kawalan tak terhingga dan kawalan tertentu.

Kawalan tak terhingga

Anda mungkin ingin menggunakan kawalan tak terhingga dalam situasi berikut:

  • Anda tidak dapat menentukan masa menunggu untuk operasi.
  • Anda tidak dapat mengesan kemajuan operasi.
  • Anda tidak mahu menunjukkan berapa lama operasi akan mengambil masa.

Image title

Kawalan tertentu

Anda mungkin ingin menggunakan kawalan ini apabila anda boleh menentukan masa menunggu untuk operasi dan mahu pengguna melihat penunjuk berdasarkan masa tersebut.

Untuk memaparkan kemajuan operasi, gunakan sifat Value untuk menetapkan angka. Untuk menetapkan peratusan bar kemajuan, gunakan sifat Minimum dan Maximum.

Image title

Kod plugin di bawah menunjukkan kepada anda cara untuk mencipta bar kemajuan menggunakan kedua-dua kawalan tak terhingga dan tertentu (hijau):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
using System;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Plugins
{
    [Plugin(AccessRights = AccessRights.None)]
    public class ProgressBarTest : Plugin
    {
        private ProgressBar _infiniteProgressBar;
        private ProgressBar _determinateProgressBar;

        protected override void OnStart()
        {
            var aspBlock = Asp.SymbolTab.AddBlock("Progress bar");

            var panel = new StackPanel() {Height = 200, Width = 200, Orientation = Orientation.Vertical};

            _infiniteProgressBar = new ProgressBar {IsIndeterminate = true, Height = 20};

            panel.AddChild(_infiniteProgressBar);

            _determinateProgressBar = new ProgressBar {IsIndeterminate = false, Height = 20};

            panel.AddChild(_determinateProgressBar);

            var autoProgressButton = new Button {Text = "Start"};

            autoProgressButton.Click += AutoProgressButton_Click;

            panel.AddChild(autoProgressButton);

            aspBlock.Child = panel;

        }

        private void AutoProgressButton_Click(ButtonClickEventArgs obj)
        {
            Timer.Start(1);
        }

        protected override void OnTimer()
        {
            _determinateProgressBar.Value++;

            Print($"Value: {_determinateProgressBar.Value}");
        }

        protected override void OnStop()
        {
            // Handle Plugin stop here
        }
    }        
}

Dialog

OpenFileDialog dan OpenFolderDialog

API cTrader Algo menyediakan antara muka OpenFileDialog untuk membolehkan pengguna memilih fail untuk algoritma. Apabila pengguna memilih fail dalam tetingkap yang terhasil, fail tersebut disalin ke folder Selected files algoritma. Algoritma boleh bekerja dengan fail di dalam folder Selected files tanpa sekatan.

Petua

Gunakan fungsi OpenFileDialog apabila anda perlu memuatkan fail data penting, fail sandaran atau konfigurasi, indikator tersuai atau skrip.

Kod di bawah menunjukkan kepada anda cara menggunakan dialog OpenFileDialog dalam indikator:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
using System;
using cAlgo.API;
using System.Text;

namespace cAlgo
{
    [Indicator(AccessRights = AccessRights.None, IsOverlay = true)]
    public class OpenFileDialogExample : Indicator
    {
        private OpenFileDialog _openFileDialog;

        protected override void Initialize()
        {
            _openFileDialog = new OpenFileDialog()
            {
                InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
                Multiselect = true,
                Title = "My Open File Dialog Title"
            };

            var showOpenFileDialog = new Button { Text = "Show Open File Dialog" };
            showOpenFileDialog.Click += showOpenFileDialog_Click;

            var panel = new StackPanel
            {
                Orientation = Orientation.Vertical,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center
            };

            panel.AddChild(showOpenFileDialog);
            Chart.AddControl(panel);
        }

        private void showOpenFileDialog_Click(ButtonClickEventArgs obj)
        {
            var result = _openFileDialog.ShowDialog();
            Print($"Result: {result} | FileName: {_openFileDialog.FileName} | FileNames: {string.Join(',', _openFileDialog.FileNames)}");
        }

        public override void Calculate(int index)
        {
        }
    }
}

Image title

API cTrader Algo menyediakan antara muka OpenFolderDialog untuk membolehkan pengguna menentukan folder untuk algoritma. Apabila pengguna memilih folder dalam tetingkap yang terhasil, semua fail dan folder dengan fail di dalam folder yang dipilih disalin ke folder Selected files algoritma.

Petua

Gunakan fungsi OpenFolderDialog apabila anda perlu memuatkan folder yang mengandungi fail data penting, fail sandaran atau konfigurasi, indikator tersuai atau skrip.

Fail dan folder yang dipilih biasanya disalin ke folder Selected files kerana algoritma boleh bekerja dengan item di dalam folder tersebut walaupun AccessRights ditetapkan kepada None.

Nota

Folder Selected files algoritma biasanya berada di laluan ini: ..\Documents\cAlgo\Data\{AlgoType}\{AlgoName}\Selected files\

Folder Selected files untuk contoh cBot berbeza daripada yang di atas: ..\Documents\cAlgo\Data\cBots\{cBotName}\{Instance-Id}\Selected files\

Kod di bawah menunjukkan kepada anda cara menggunakan dialog OpenFolderDialog dalam indikator:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using System;
using cAlgo.API;

namespace cAlgo
{
    [Indicator(AccessRights = AccessRights.None, IsOverlay = true)]
    public class OpenFolderDialogExample : Indicator
    {
        private OpenFolderDialog _openFolderDialog;

        protected override void Initialize()
        {
            _openFolderDialog = new OpenFolderDialog()
            {
                InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
                Title = "My Open Folder Dialog Title"
            };

            var showOpenFolderDialog = new Button { Text = "Show Open Folder Dialog" };
            showOpenFolderDialog.Click += showOpenFolderDialog_Click;

            var panel = new StackPanel
            {
                Orientation = Orientation.Vertical,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center
            };

            panel.AddChild(showOpenFolderDialog);
            Chart.AddControl(panel);
        }

        private void showOpenFolderDialog_Click(ButtonClickEventArgs obj)
        {
            var result = _openFolderDialog.ShowDialog();
            Print($"Result: {result} | FolderName: {_openFolderDialog.FolderName}");
        }

        public override void Calculate(int index)
        {
        }
    }
}

Image title

SaveFileDialog

API cTrader Algo menyediakan antara muka SaveFileDialog untuk membolehkan pengguna menyimpan fail (secara tempatan) ke komputer mereka. Apabila tetingkap yang berkaitan muncul, pengguna memilih folder di mana mereka ingin menyimpan fail dan memasukkan nama untuk fail tersebut. Fail kemudian disimpan di lokasi yang ditentukan.

Petua

Gunakan fungsi SaveFileDialog apabila anda perlu melakukan mana-mana yang berikut:

  • Menyimpan laporan prestasi, hasil ujian belakang, fail konfigurasi atau data pengoptimuman.
  • Mengeksport log dagangan, jurnal operasi atau data aktiviti pengguna umum.
  • Menyimpan indikator tersuai, data untuk carta dan visualisasi atau parameter untuk strategi.

Kod di bawah menunjukkan kepada anda cara menggunakan dialog SaveFileDialog dalam indikator:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
using System;
using cAlgo.API;
using System.Text;

namespace cAlgo
{
    [Indicator(AccessRights = AccessRights.None, IsOverlay = true)]
    public class SaveFileDialogExample : Indicator
    {
        private SaveFileDialog _saveFileDialog;

        protected override void Initialize()
        {
            _saveFileDialog = new SaveFileDialog()
            {
                InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
                Title = "My Save File Dialog Title"
            };

            var showSaveFileDialogText = new Button { Text = "Show Save File Dialog (Set Content as text)" };
            var showSaveFileDialogBytes = new Button { Text = "Show Save File Dialog (Set Content as bytes)" };

            showSaveFileDialogText.Click += showSaveFileDialogText_Click;
            showSaveFileDialogBytes.Click += showSaveFileDialogBytes_Click;

            var panel = new StackPanel
            {
                Orientation = Orientation.Vertical,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center
            };
            panel.AddChild(showSaveFileDialogText);
            panel.AddChild(showSaveFileDialogBytes);
            Chart.AddControl(panel);
        }

        private void showSaveFileDialogText_Click(ButtonClickEventArgs obj)
        {
            var result = _saveFileDialog.ShowDialog();
            Print($"Result: {result}");
            if (result != FileDialogResult.Cancel)
            {
                _saveFileDialog.WriteToFile("Test in text");
            }
        }

        private void showSaveFileDialogBytes_Click(ButtonClickEventArgs obj)
        {
            var result = _saveFileDialog.ShowDialog();
            Print($"Result: {result}");
            if (result != FileDialogResult.Cancel)
            {
                _saveFileDialog.WriteToFile(Encoding.UTF8.GetBytes("Test in bytes"));
            }
        }

        public override void Calculate(int index)
        {
        }
    }
}

Kawalan boleh diseret

Kawalan boleh diseret kawasan carta

Antara muka ChartDraggable dan ChartDraggables menyediakan jenis yang membolehkan anda menambah kawalan boleh diseret yang mampu menampung kawalan lain dan elemen berbeza pada carta. Kawalan boleh diseret ini memudahkan pengguna untuk berinteraksi dengan pelbagai elemen carta.

Nota

Kawalan boleh diseret hanya boleh dipindahkan atau diletakkan semula dalam carta di mana ia telah ditambah.

Kod ini menunjukkan kepada anda cara untuk mencipta indikator yang menambah dua kawalan yang boleh dipindahkan dalam carta:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
using System;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo
{
    [Indicator(AccessRights = AccessRights.None)]
    public class DragControl : Indicator
    {
        protected override void Initialize()
        {
            var draggable = Chart.Draggables.Add();
            var draggable2 = IndicatorArea.Draggables.Add();

            draggable.Child = GetDraggableChildWebView();
            draggable2.Child = GetDraggableChildText();

            draggable.LocationChanged += draggable_LocationChanged;
            draggable2.LocationChanged += draggable2_LocationChanged;
        }

        public override void Calculate(int index)
        {
            // Calculate value at specified index
            // Result[index] = 
        }

        private StackPanel GetDraggableChildWebView()
        {
            var stackPanel = new StackPanel
            {
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                BackgroundColor = Color.Gold
            };

            var webView = new WebView() {Height = 500, Width = 300};

            webView.Loaded += webView_Loaded;

            stackPanel.AddChild(webView);

            return stackPanel;
        }

        private StackPanel GetDraggableChildText()
        {
            var stackPanel = new StackPanel
            {
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                BackgroundColor = Color.Gold
            };
            var text_block = new TextBlock
                 {
                     Text = "Testing draggable controls",
                     Margin = 5,
                     ForegroundColor = Color.Black,
                     FontWeight = FontWeight.ExtraBold
                 };

            stackPanel.AddChild(text_block);

            return stackPanel;
        }


        private void webView_Loaded(WebViewLoadedEventArgs obj)
        {
            obj.WebView.NavigateAsync("https://www.youtube.com/");
        }

        private void draggable_LocationChanged(ChartDraggableLocationChangedEventArgs obj)
        {
            Print($"Draggable '{obj.Draggable.Id}' location changed to: ({obj.Draggable.X}, {obj.Draggable.Y})");
        }

        private void draggable2_LocationChanged(ChartDraggableLocationChangedEventArgs obj)
        {
            Print($"Draggable '{obj.Draggable.Id}' location changed to: ({obj.Draggable.X}, {obj.Draggable.Y})");
        }
    }
}

Kawalan boleh diseret tetingkap aplikasi

Antara muka ApplicationDraggable dan ApplicationDraggables menyediakan jenis yang digunakan untuk menambah kawalan terapung yang boleh dipindahkan secara individu merentasi keseluruhan tetingkap aplikasi cTrader. Kawalan sedemikian membolehkan anda mencipta antara muka pengguna yang interaktif dan dinamik.

Nota

Daripada tiga jenis algoritma, hanya plugin dibenarkan untuk melaksanakan kawalan boleh diseret seluruh aplikasi.

Kod ini menunjukkan kepada anda cara untuk mencipta plugin yang menambah komponen WebView dan blok teks dalam dua tetingkap berasingan, yang boleh dipindahkan merentasi keseluruhan UI cTrader:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
using System;
using cAlgo.API;
using cAlgo.API.Internals;

namespace cAlgo.Plugins
{
    [Plugin(AccessRights = AccessRights.None)]
    public class ApplicationLevelDraggables : Plugin
    {
        private ApplicationDraggable _webDraggable;
        private ApplicationDraggable _textDraggable;

        protected override void OnStart()
        {
            _webDraggable = Application.Draggables.Add();
            _webDraggable.Child = GetDraggableChildWebView();
            _webDraggable.LocationChanged += OnDraggableLocationChanged;

            _textDraggable = Application.Draggables.Add();
            _textDraggable.Child = GetDraggableChildText();
            _textDraggable.LocationChanged += OnDraggableLocationChanged;
        }

        private void OnDraggableLocationChanged(ApplicationDraggableLocationChangedEventArgs args)
        {
            Print($"Draggable '{args.Draggable.Id}' location changed to: ({args.Draggable.X}, {args.Draggable.Y})");
        }

        private StackPanel GetDraggableChildWebView()
        {
            var stackPanel = new StackPanel
            {
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                BackgroundColor = Color.Gold
            };

            var webView = new WebView { Width = 300, Height = 200 };
            webView.Loaded += (args) => args.WebView.NavigateAsync("https://www.youtube.com/");

            stackPanel.AddChild(webView);

            return stackPanel;
        }

        private StackPanel GetDraggableChildText()
        {
            var stackPanel = new StackPanel
            {
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                BackgroundColor = Color.Gold
            };

            var textBlock = new TextBlock
            {
                Text = "Testing Application-level draggable",
                Margin = 5,
                ForegroundColor = Color.Black,
                FontWeight = FontWeight.ExtraBold
            };

            stackPanel.AddChild(textBlock);

            return stackPanel;
        }
    }
}

Kawalan tab

Kelas TabControl menyediakan jenis yang membolehkan anda mencipta pelbagai tab untuk algoritma. Tab ini boleh digunakan untuk menyimpan elemen berkaitan bersama atau menyampaikan pandangan berasingan untuk fungsi.

Kod ini menunjukkan kepada anda cara menggunakan tab dalam plugin yang ditambah ke Panel Simbol Aktif:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Internals;

namespace cAlgo.Plugins
{
    [Plugin(AccessRights = AccessRights.FullAccess)]
    public class TabControlSimple : Plugin
    {
        private TabControl _tabControl;

        protected override void OnStart()
        {
            _tabControl = new TabControl
            {
                Height = 200,
                TabStripPlacement = Dock.Left 
            };

            var firstTab = new TabItem
            {
                Header = new TextBlock { Text = "First Tab" },
                Content = new TextBlock { Text = "First Tab Content", BackgroundColor = Color.Red }
            };

            var secondTab = new TabItem
            {
                Header = new TextBlock { Text = "Second Tab" },
                Content = new TextBlock { Text = "Second Tab Content" }
            };

            _tabControl.AddTab(firstTab);
            _tabControl.AddTab(secondTab);

            _tabControl.SelectedTabChanged += TabControl_SelectedTabChanged;

            _tabControl.SelectedTab = secondTab;

            var panel = new StackPanel { Orientation = Orientation.Vertical };
            panel.AddChild(_tabControl);

            var asp = Asp.SymbolTab.AddBlock("Simple Tab Control");
            asp.Child = panel;
            asp.Height = 300;
        }

        private void TabControl_SelectedTabChanged(TabControlSelectedTabChangedEventArgs obj)
        {
            Print($"Selected tab changed to: {obj.SelectedTab?.UniqueId}");
        }

        protected override void OnStop()
        {
        }
    }
}

Kawalan tersuai

Kawalan tersuai ialah kawalan yang pada asasnya dibina daripada beberapa kawalan yang telah ditentukan sebelumnya. Dengan kata lain, ia adalah kawalan di mana kawalan lain membentuk kandungannya.

Kawalan tersuai bertindak sebagai kelas boleh guna semula sama seperti kawalan terbina dalam.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
using cAlgo.API;

namespace ChartControlsTest
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class ChartControls : Indicator
    {
        [Parameter("# Of Text Areas", DefaultValue = 4)]
        public int NumberOfTextAreas { get; set; }

        protected override void Initialize()
        {
            var panel = new WrapPanel
            {
                Orientation = Orientation.Horizontal,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center
            };

            for (int i = 0; i < NumberOfTextAreas; i++)
            {
                var textArea = new TextArea
                {
                    HorizontalAlignment = HorizontalAlignment.Right,
                    VerticalAlignment = VerticalAlignment.Stretch,
                    Margin = 5,
                };

                panel.AddChild(textArea);
            }

            Chart.AddControl(panel);
        }

        public override void Calculate(int index)
        {
        }
    }

    public class TextArea : CustomControl
    {
        private readonly TextBox _textBox;

        public TextArea()
        {
            _textBox = new TextBox
            {
                TextAlignment = TextAlignment.Left,
                TextWrapping = TextWrapping.Wrap,
                AcceptsReturn = true,
                AcceptsTab = true,
                Width = 300,
                Height = 200,
            };

            AddChild(_textBox);
        }
    }
}

Tika indikator ini sepatutnya memaparkan empat kotak teks terus di tengah-tengah carta utama.

Atur kawalan dengan panel

Untuk memudahkan penggunaan kawalan, anda mungkin ingin meletakkan beberapa kawalan ke dalam kumpulan tersendiri dengan kedudukan tersendiri dalam UI. Untuk melakukan ini, anda boleh menggunakan kelas Panels dan terbitannya.

Anggap panel sebagai kawalan dengan kawalan lain sebagai kandungannya. cTrader menyokong lima kelas berbeza yang mewarisi dari kelas asas Panels (yang sendirinya mewarisi dari kelas Control):

  • Canvas
  • DockPanel
  • Grid
  • StackPanel
  • WrapPanel

Setiap kelas di atas menggunakan susun atur panel dan strategi peletakan yang berbeza seperti yang dibincangkan di bawah.

Kanvas

Kanvas ialah panel yang membolehkan peletakan kawalan berdasarkan koordinat X dan Y tertentu.

Perlu diingat bahawa paksi X dan Y adalah berbeza daripada yang digunakan oleh objek carta atau lukisan. Koordinat X dan Y yang digunakan oleh kelas Canvas mewakili nilai angka bermula dari (0, 0) dari sudut kiri atas carta.

Pertimbangkan contoh berikut:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
using cAlgo.API;

namespace ChartControlsTest
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class ChartControls : Indicator
    {
        [Parameter(DefaultValue = "Click Me")]
        public string Text { get; set; }

        [Parameter(DefaultValue = 0)]
        public double Left { get; set; }

        [Parameter(DefaultValue = 0)]
        public double Top { get; set; }

        [Parameter(DefaultValue = 0)]
        public double Margin { get; set; }

        [Parameter(DefaultValue = 10)]
        public double Padding { get; set; }

        protected override void Initialize()
        {
            var button = new Button
            {
                Text = Text,
                Left = Left,
                Top = Top,
                Margin = Margin,
                Padding = Padding
            };

            button.Click += Button_Click;

            var canvas = new Canvas();

            /* We add our button control to the canvas
            panel. */
            canvas.AddChild(button);

            // We add our canvas panel to the chart.
            Chart.AddControl(canvas);
        }

        private void Button_Click(ButtonClickEventArgs obj)
        {
            obj.Button.Text = "You clicked me, thanks";
        }

        public override void Calculate(int index)
        {
        }
    }
}

Apabila mencipta tika indikator di atas, anda sepatutnya melihat butang Click me di sudut kiri atas carta.

Sifat Top kawalan menentukan kedudukannya pada paksi Y. Sementara itu, sifat Left menentukan kedudukannya pada paksi X.

Kod di atas juga menggunakan sifat Padding dan Margin. Padding merujuk kepada jarak antara kandungan kawalan dan sempadan luarnya. Margin ialah jarak antara kawalan dan sempadan induknya. Sifat Padding dan Margin boleh digunakan untuk semua panel, bukan hanya kelas kanvas. Ia berguna untuk mengurus jarak antara kawalan anda.

Dalam kebanyakan kes, kelas Canvas digunakan untuk mengumpulkan hanya sebilangan kecil kawalan.

Panel dok

Kelas DockPanel digunakan untuk mendok (meletakkan) kawalan di lokasi statik pada carta. Terdapat empat kedudukan dok yang mungkin:

  • Atas
  • Bawah
  • Kiri
  • Kanan

Setiap kawalan mempunyai sifat Dock. Apabila menggunakan kelas DockPanel, anda boleh menggunakan sifat ini untuk meletakkan kawalan di dalam DockPanel. Ini ditunjukkan dalam contoh berikut:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
using cAlgo.API;

namespace ChartControlsTest
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class ChartControls : Indicator
    {
        [Parameter(DefaultValue = Dock.Top)]
        public Dock TextBoxDock { get; set; }

        [Parameter(DefaultValue = Dock.Bottom)]
        public Dock ButtonDock { get; set; }

        private TextBox _textBox;

        protected override void Initialize()
        {
            _textBox = new TextBox
            {
                Margin = 5,
                Text = "Write here...",
                ForegroundColor = Color.Yellow,
                Dock = TextBoxDock,
                Width = 200
            };

            var button = new Button
            {
                Text = "Tell what I wrote?",
                Dock = ButtonDock,
                Width = 200
            };

            button.Click += Button_Click;

            var dockPanel = new DockPanel
            {
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
            };

            dockPanel.AddChild(_textBox);
            dockPanel.AddChild(button);

            Chart.AddControl(dockPanel);
        }

        private void Button_Click(ButtonClickEventArgs obj)
        {
            obj.Button.Text = $"You wrote: {_textBox.Text}";
        }

        public override void Calculate(int index)
        {
        }
    }
}

Apabila mencipta tika indikator ini, anda sepatutnya melihat panel dok di tengah carta yang mengandungi medan teks dan butang boleh klik.

Perhatikan bahawa panel dok boleh diisi sama ada secara mendatar atau menegak. Anda tidak boleh menggunakan kedua-dua penjajaran ini pada masa yang sama. Orientasi panel dok ditetapkan secara automatik apabila menyediakan kawalan pertama dalam DockPanel. Jika sifat Dock kawalan pertama ditetapkan sama ada kepada Top atau Bottom, keseluruhan DockPanel akan berorientasi secara menegak, dan sebaliknya.

Panel tindanan

Panel tindanan adalah salah satu kawalan yang paling kerap digunakan kerana kesederhanaan dan kebolehgunaannya. Panel tindanan menjajarkan kawalan anak sama ada secara mendatar atau menegak satu demi satu. Seperti yang ditunjukkan di bawah, anda hanya perlu menetapkan orientasinya dan kelas akan mengurus selebihnya:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
using cAlgo.API;

namespace ChartControlsTest
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class ChartControls : Indicator
    {
        [Parameter(DefaultValue = Orientation.Vertical)]
        public Orientation Orientation { get; set; }

        protected override void Initialize()
        {
            var firstNameTextBox = new TextBox
            {
                Margin = 5,
                Text = "First Name...",
                Width = 200
            };

            var lastNameTextBox = new TextBox
            {
                Margin = 5,
                Text = "Last Name...",
                Width = 200
            };

            var isMarriedCheckBox = new CheckBox
            {
                Text = "Is Married?",
                Margin = 5,
            };

            var submitButton = new Button
            {
                Text = "Submit",
                Margin = 5
            };

            var stackPanel = new StackPanel
            {
                Orientation = Orientation,
                HorizontalAlignment = HorizontalAlignment.Right,
                VerticalAlignment = VerticalAlignment.Bottom,
                BackgroundColor = Color.FromArgb(80, Color.Gold),
                Margin = 20
            };

            stackPanel.AddChild(firstNameTextBox);
            stackPanel.AddChild(lastNameTextBox);
            stackPanel.AddChild(isMarriedCheckBox);
            stackPanel.AddChild(submitButton);

            Chart.AddControl(stackPanel);
        }

        public override void Calculate(int index)
        {
        }
    }
}

Selepas mencipta tika indikator, anda sepatutnya melihat panel tindanan mendatar dengan dua medan teks dan butang 'Submit' di sudut kanan bawah carta utama.

Panel balut

Panel balut kebanyakannya serupa dengan panel tindanan. Walau bagaimanapun, apabila tidak cukup ruang untuk memuatkan semua elemen panel balut, ia akan secara automatik membalut kawalan yang selebihnya ke baris seterusnya pada paksi Y.

Grid

Anggap grid sebagai lembaran hamparan dengan bilangan lajur dan baris yang ditetapkan. Apabila menggunakan grid, anda boleh menambah kawalan ke setiap sel berasingan.

Seperti yang ditunjukkan di bawah, apabila anda mencipta tika kelas Grid, anda memasukkan bilangan baris dan lajurnya sebagai hujah integer. Apabila menambah anak atau kawalan baharu, anda juga perlu menentukan bilangan baris dan lajur anak.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
using cAlgo.API;

namespace ChartControlsTest
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class ChartControls : Indicator
    {
        [Parameter("Grid Rows #", DefaultValue = 10)]
        public int GridRowsNumber { get; set; }

        [Parameter("Grid Columns #", DefaultValue = 2)]
        public int GridColumnsNumber { get; set; }

        protected override void Initialize()
        {
            var grid = new Grid(GridRowsNumber, GridColumnsNumber)
            {
                BackgroundColor = Color.Gold,
                Opacity = 0.6,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                ShowGridLines = true
            };

            for (int iRow = 0; iRow < GridRowsNumber; iRow++)
            {
                for (int iColumn = 0; iColumn < GridColumnsNumber; iColumn++)
                {
                    grid.AddChild(new TextBlock
                    {
                        Text = string.Format("Row {0} and Column {1}", iRow, iColumn),
                        Margin = 5,
                        ForegroundColor = Color.Black,
                        FontWeight = FontWeight.ExtraBold
                    }, iRow, iColumn);
                }
            }

            Chart.AddControl(grid);
        }

        public override void Calculate(int index)
        {
        }
    }
}

Apabila mencipta tika indikator di atas, anda sepatutnya melihat grid 10x2 tepat di tengah carta.

Letakkan kawalan dalam koordinat harga dan masa

Selain kawalan panel, cTrader membolehkan penentuan koordinat harga dan masa untuk kawalan terus dalam kawasan carta. Kaedah AddControl() dan MoveControl() menyediakan pembangun algo dengan fungsi ini.

Gunakan penindihan kaedah berikut untuk mengurus koordinat kawalan carta anda bergantung pada pilihan anda.

Untuk menambah kawalan carta ke kawasan carta atau indikator pada koordinat indeks bar dan harga (x, y) mutlak.

1
void AddControl(ControlBase control, int barIndex, double y)

Untuk menggerakkan kawalan carta ke kawasan carta atau indikator pada koordinat indeks bar dan harga (x, y) mutlak.

1
void MoveControl(ControlBase control, int barIndex, double y)

Untuk menambah kawalan carta ke kawasan carta atau indikator pada koordinat masa dan harga (x, y) mutlak.

1
void AddControl(ControlBase control, DateTime time, double y)

Untuk menggerakkan kawalan carta ke kawasan carta atau indikator pada koordinat masa dan harga (x, y) mutlak.

1
void MoveControl(ControlBase control, DateTime time, double y)

Untuk menambah kawalan carta ke kawasan carta atau indikator pada koordinat masa (x) mutlak.

1
void AddControl(ControlBase control, DateTime time)

Untuk menggerakkan kawalan carta ke kawasan carta atau indikator pada koordinat masa (x) mutlak.

1
void MoveControl(ControlBase control, DateTime time)

Untuk menambah kawalan carta ke kawasan carta atau indikator pada koordinat indeks bar (x) mutlak.

1
void AddControl(ControlBase control, int barIndex)

Untuk menggerakkan kawalan carta ke kawasan carta atau indikator pada koordinat indeks bar (x) mutlak.

1
void MoveControl(ControlBase control, int barIndex)

Untuk menambah kawalan carta ke kawasan carta atau indikator pada koordinat harga (y) mutlak.

1
void AddControl(ControlBase control, double y)

Untuk menggerakkan kawalan carta ke kawasan carta atau indikator pada koordinat harga (y) mutlak.

1
void MoveControl(ControlBase control, double y)

Kelas parameter ControlBase boleh merangkumi mana-mana kelas bawahan lain (Control, Button, dll.) untuk kaedah dipanggil mengikut tandatangan di atas.

Contoh cBot berikut menambah butang Click me! di atas bar terakhir pada carta. Butang tersebut bergerak ke hadapan bersama-sama dengan setiap bar baharu yang ditambah. Selepas mengklik butang tersebut, kotak mesej akan muncul pada skrin.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class ButtonTest : Robot
    {
        [Parameter(DefaultValue = "Hello world!")]
        public string Message { get; set; }

        Button button;

        protected override void OnStart() 
        {
            button = new Button
            {
                Text = "Click me!"
            };

            button.Click += Button_Click;

            Chart.AddControl(button, Bars.Count - 1);
        }

        protected override void OnBar() 
        {
            Chart.MoveControl(button, Bars.Count - 1);
        }

        private void Button_Click(ButtonClickEventArgs obj)
        {
            MessageBox.Show(Message, "Title/Caption");
        }
    }
}

Amaran

Bilangan kawalan akar yang boleh ditambah pada carta adalah terhad kepada 100 kerana kemungkinan isu prestasi. Had ini hanya terpakai untuk satu tika algoritma dan kawalan yang dilampirkan pada harga dan bar.

Sifat penampan dan margin

Sifat Margin menentukan ruang antara sempadan objek Control dan induknya (carta, panel, sempadan, dll.).

Sementara itu, sifat Padding menentukan ruang antara kandungan kawalan dan sempadannya. Anda boleh mengubah nilai sifat supaya semuanya berbeza untuk sisi yang berbeza.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
using cAlgo.API;

namespace ChartControlsTest
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class ChartControls : Indicator
    {
        [Parameter(DefaultValue = "Click Me")]
        public string Text { get; set; }

        [Parameter(DefaultValue = 0)]
        public double Left { get; set; }

        [Parameter(DefaultValue = 0)]
        public double Top { get; set; }

        [Parameter(DefaultValue = 0, Group = "Margin")]
        public double LeftMargin { get; set; }

        [Parameter(DefaultValue = 0, Group = "Margin")]
        public double TopMargin { get; set; }

        [Parameter(DefaultValue = 0, Group = "Margin")]
        public double RightMargin { get; set; }

        [Parameter(DefaultValue = 0, Group = "Margin")]
        public double BottomMargin { get; set; }

        [Parameter(DefaultValue = 5, Group = "Padding")]
        public double LeftPadding { get; set; }

        [Parameter(DefaultValue = 5, Group = "Padding")]
        public double TopPadding { get; set; }

        [Parameter(DefaultValue = 5, Group = "Padding")]
        public double RightPadding { get; set; }

        [Parameter(DefaultValue = 5, Group = "Padding")]
        public double BottomPadding { get; set; }

        protected override void Initialize()
        {
            var button = new Button
            {
                Text = Text,
                Left = Left,
                Top = Top,
                Margin = new Thickness(LeftMargin, TopMargin, RightMargin, BottomMargin),
                Padding = new Thickness(LeftPadding, TopPadding, RightPadding, BottomPadding)
            };

            button.Click += Button_Click;

            var canvas = new Canvas();

            canvas.AddChild(button);

            Chart.AddControl(canvas);
        }

        private void Button_Click(ButtonClickEventArgs obj)
        {
            obj.Button.Text = "You clicked me, thanks";
        }

        public override void Calculate(int index)
        {
        }
    }
}

Tika indikator ini akan mencipta butang kelabu Click me di sudut kiri atas carta. Ubah suai parameter dalam tetingkap Add instance atau Modify parameters untuk melihat bagaimana nilai margin dan penampan yang berbeza mengubah cara kawalan dipaparkan.

Gaya

Apabila menggunakan gaya, anda boleh memberikan rupa yang serupa kepada beberapa jenis kawalan yang berbeza. Ini amat berguna apabila berurusan dengan bilangan kawalan yang besar (lima atau lebih).

Kelas Style membolehkan penetapan nilai untuk pelbagai sifat kawalan seperti Margin atau BackgroundColor. Selepas itu, anda boleh menggunakan semula nilai-nilai ini sebagai templat untuk pelbagai kawalan lain.

Kita juga boleh mewujudkan rupa yang konsisten untuk pelbagai kawalan tanpa menggunakan kelas Style sama sekali.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
using cAlgo.API;

namespace ChartControlsTest
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class ChartControls : Indicator
    {
        protected override void Initialize()
        {
            var firstTextBox = new TextBox
            {
                ForegroundColor = Color.Red,
                Margin = 5,
                FontFamily = "Cambria",
                FontSize = 12,
                Text = "Type...",
                Width = 150
            };

            var secondTextBox = new TextBox
            {
                ForegroundColor = Color.Red,
                Margin = 5,
                FontFamily = "Cambria",
                FontSize = 12,
                Text = "Type...",
                Width = 150
            };

            var thirdTextBox = new TextBox
            {
                ForegroundColor = Color.Red,
                Margin = 5,
                FontFamily = "Cambria",
                FontSize = 12,
                Text = "Type...",
                Width = 150
            };

            var panel = new StackPanel
            {
                Orientation = Orientation.Vertical,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center
            };

            panel.AddChild(firstTextBox);
            panel.AddChild(secondTextBox);
            panel.AddChild(thirdTextBox);

            Chart.AddControl(panel);
        }

        public override void Calculate(int index)
        {
        }
    }
}

Berikut adalah cara penggunaan kelas Style boleh memudahkan kerja dengan pelbagai kawalan.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
using cAlgo.API;

namespace ChartControlsTest
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class ChartControls : Indicator
    {
        protected override void Initialize()
        {
            var textBoxStyle = new Style();

            textBoxStyle.Set(ControlProperty.ForegroundColor, Color.Red);
            textBoxStyle.Set(ControlProperty.Margin, 5);
            textBoxStyle.Set(ControlProperty.FontFamily, "Cambria");
            textBoxStyle.Set(ControlProperty.FontSize, 12);
            textBoxStyle.Set(ControlProperty.Width, 150);

            var firstTextBox = new TextBox
            {
                Text = "Type...",
                Style = textBoxStyle
            };

            var secondTextBox = new TextBox
            {
                Text = "Type...",
                Style = textBoxStyle
            };

            var thirdTextBox = new TextBox
            {
                Text = "Type...",
                Style = textBoxStyle
            };

            var panel = new StackPanel
            {
                Orientation = Orientation.Vertical,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center
            };

            panel.AddChild(firstTextBox);
            panel.AddChild(secondTextBox);
            panel.AddChild(thirdTextBox);

            Chart.AddControl(panel);
        }

        public override void Calculate(int index)
        {
        }
    }
}

Kedua-dua cebisan kod di atas sepatutnya memaparkan kawalan yang sama jika anda melancarkan contoh indikator masing-masing.

Anda juga boleh menggunakan kelas Style untuk mengubah rupa kawalan berdasarkan keadaannya.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
using cAlgo.API;

namespace ChartControlsTest
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class ChartControls : Indicator
    {
        protected override void Initialize()
        {
            var textBoxStyle = new Style();

            textBoxStyle.Set(ControlProperty.ForegroundColor, Color.Red);
            textBoxStyle.Set(ControlProperty.Margin, 5);
            textBoxStyle.Set(ControlProperty.FontFamily, "Cambria");
            textBoxStyle.Set(ControlProperty.FontSize, 12);
            textBoxStyle.Set(ControlProperty.Width, 150);
            // Here we change the foreground color to Yellow if mouse hover over the textbox
            textBoxStyle.Set(ControlProperty.ForegroundColor, Color.Yellow, ControlState.Hover);

            var firstTextBox = new TextBox
            {
                Text = "Type...",
                Style = textBoxStyle
            };

            var secondTextBox = new TextBox
            {
                Text = "Type...",
                Style = textBoxStyle
            };

            var thirdTextBox = new TextBox
            {
                Text = "Type...",
                Style = textBoxStyle
            };

            var panel = new StackPanel
            {
                Orientation = Orientation.Vertical,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center
            };

            panel.AddChild(firstTextBox);
            panel.AddChild(secondTextBox);
            panel.AddChild(thirdTextBox);

            Chart.AddControl(panel);
        }

        public override void Calculate(int index)
        {
        }
    }
}

Imej

Kawalan Image boleh digunakan untuk memaparkan imej yang disimpan secara setempat. Kawalan Image menggunakan kelas Bitmap .NET, yang bermaksud ia menyokong kebanyakan format imej popular seperti berikut:

  • .PNG
  • .JPG
  • .BMP
  • .GIF
  • .TIFF

Rujuk dokumentasi kelas Bitmap .NET untuk mengetahui lebih lanjut mengenainya.

Untuk menggunakan kawalan Image, tetapkan sifat Source kepada data fail imej dalam tatasusunan bait (byte[]).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
using cAlgo.API;
using System.IO;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class ImageSample : Indicator
    {
        [Parameter("Image File Path")]
        public string ImageFilePath { get; set; }

        protected override void Initialize()
        {
            if (File.Exists(ImageFilePath) is false)
            {
                Print($"Image not found: {ImageFilePath}");

                return;
            }

            var imageBytes = File.ReadAllBytes(ImageFilePath);

            var image = new Image
            {
                Source = imageBytes,
                Width = 200,
                Height = 200,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center
            };

            Chart.AddControl(image);
        }

        public override void Calculate(int index)
        {
        }
    }
}

Selepas melancarkan contoh indikator di atas, anda sepatutnya tidak melihat apa-apa yang baharu pada carta utama. Walau bagaimanapun, masukkan laluan fail yang sah sebagai nilai parameter (Laluan Fail Imej), dan anda sepatutnya melihat imej yang dipilih dipaparkan di tengah-tengah skrin.

Anda juga boleh menggunakan sumber projek anda untuk menyimpan imej dan memaparkannya melalui kawalan Image. Untuk berbuat demikian, buka sumber projek dalam Visual Studio dan beralih ke tab Resources. Di dalamnya, cipta sumber baharu dan tambah imej sedia ada. Selepas itu, anda akan dapat menggunakan imej ini sebagai sumber dalam mana-mana kawalan Image melalui sifat Project_Name_Space.Properties.Resources._Image_Name.

Sebagai contoh, salin imej di bawah dan simpan sebagai "image.png" pada sistem anda:

Image title

Cipta indikator baharu dalam cTrader, tetapkan namanya kepada "Image Sample", dan bukanya melalui Visual Studio. Selepas itu, tambah indikator logo projek sebagai sumber. Untuk berbuat demikian, klik kanan pada projek anda, pilih Properties dan klik Resources, kemudian klik Create and manage assembly resources. Salin fail logo.png ke dalam tab yang baru dibuka.

Salin kod di bawah ke fail kod sumber utama indikator anda:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using cAlgo.API;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class ImageSample : Indicator
    {
        protected override void Initialize()
        {
            var image = new Image
            {
                Source = Image_Sample.Properties.Resources.logo,
                Width = 200,
                Height = 200,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center
            };

            Chart.AddControl(image);
        }

        public override void Calculate(int index)
        {
        }
    }
}

Selepas mencipta contoh indikator ini, anda sepatutnya melihat output berikut.

Image title

Nota

Saiz maksimum untuk imej ialah 10 MB.