انتقل إلى المحتوى

عناصر التحكم

تتيح عناصر التحكم بعض التفاعلات التي تتضمن cBots والمؤشرات والإضافات. باستخدام الدليل أدناه، يمكنك بسهولة إنشاء عناصر تحكم واجهة المستخدم الأساسية والمتقدمة مباشرة على الرسم البياني.

هناك العديد من الفئات المدمجة التي تمثل عناصر التحكم الشائعة مثل الأزرار وكتل النص ومربعات النص والأشكال. ومع ذلك، يمكنك أيضًا إنشاء عناصر تحكم مخصصة.

انظر إلى المثال التالي:

 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)
        {
        }
    }
}

إذا قمت ببناء المؤشر أعلاه وإنشاء مثيل له، يجب أن ترى زر انقر هنا رمادي اللون في وسط الرسم البياني تمامًا.

الفرق بين عناصر التحكم وكائنات الرسم البياني

في قسم سابق، تناولنا بالفعل كائنات الرسم البياني. تُمكّن عناصر التحكم المستخدمين من التفاعل مع خوارزميات cBot والمؤشرات. وعلى العكس من ذلك، تتيح كائنات الرسم البياني الفرصة لرسم شيء ما على مخطط التداول أو في نافذة إخراج مؤشر منفصلة.

تشتق عناصر التحكم في الرسم البياني من فئة ControlBase بينما تشتق كائنات الرسم البياني من فئة ChartObject.

يتم وضع عناصر التحكم في الرسم البياني بشكل ثابت باستخدام خيارات محاذاة مختلفة. في حين يمكن وضع كائنات الرسم البياني بنفس الطريقة تمامًا، يمكن أيضًا تغيير موضعها ديناميكيًا اعتمادًا على إحداثيات X و Y معينة.

وبالمثل لكائنات الرسم البياني، يمكن إضافة عناصر التحكم في الرسم البياني إلى كل من الرسم البياني الرئيسي وأي نوافذ إخراج للمؤشرات (إن وجدت). يتم تقديم مثال على هذا الوضع أدناه:

 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)
        {
        }
    }
}

بعد إنشاء نسخة من المؤشر، يجب أن ترى زر انقر هنا في نافذة إخراج المؤشر.

ColorPicker

يُمكّن عنصر التحكم ColorPicker المتداولين من اختيار اللون المفضل لديهم للعناصر أو الكائنات الرئيسية في cTrader. على سبيل المثال، قد يدمج المطور عنصر التحكم ColorPicker في خوارزمية cBot التي ترسم خطوط الاتجاه بحيث يمكن للمستخدمين اختيار اللون المفضل لديهم لكل خط اتجاه. يسهل هذا الإعداد على المتداولين التمييز بين أنواع خطوط الاتجاه المختلفة.

يمكن أيضًا لإضافة تضيف مؤشرات إلى الرسوم البيانية تنفيذ عنصر التحكم ColorPicker حيث تتيح هذه الميزة للمستخدمين اختيار لون لخطوط المؤشر المختلفة.

عندما ينقر المستخدمون على مربع اللون، يظهر منتقي الألوان. يمكن للمستخدمين بعد ذلك الاختيار بين الألوان القياسية والمخصصة.

نموذج الكود:

 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

يُمكّن عنصر التحكم DropZone المتداولين من تنفيذ إجراءات السحب والإفلات التي تتضمن خوارزميات cBot أو المؤشرات أو الإضافات. لتنفيذ عنصر التحكم هذا في خوارزميتك، استخدم فئة DropZone. يمكن التعامل مع عنصر التحكم DropZone مثل أي عنصر تحكم آخر.

عندما يقوم المستخدم بإسقاط ملف أو مجلد متوافق في المربع، يتم إنشاء حدث Dropped. عندما يقوم المستخدم بإسقاط مجلد أو عدة مجلدات في المربع، تتم معالجة ونسخ الملفات المتوافقة فقط ذات الامتدادات المحددة في FilterExtensions.

ملاحظة

عادةً ما يتم نسخ الملفات التي تم إسقاطها وحفظها في هذا الموقع: ..\Documents\cAlgo\Data\{AlgoType}\{AlgoName}\Selected Files\

يختلف الموقع لنسخ خوارزمية cBot عن الموقع أعلاه: ..\Documents\cAlgo\Data\cBots\{cBotName}\{unique-instance-number}\Selected files\

يوضح لك كود الإضافة هذا كيفية إضافة عنصر تحكم DropZone إلى 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

يعرض عنصر التحكم ProgressBar تقدم العملية الجارية. تجعل أشرطة التقدم الخوارزميات أكثر سهولة للمستخدم وتساعد في إدارة توقعات المتداولين فيما يتعلق بوقت الانتظار لعمليات معينة.

تتيح واجهة برمجة تطبيقات cTrader Algo للمطورين إضافة نوعين من عناصر التحكم ProgressBar: التحكم اللانهائي والتحكم المحدد.

التحكم اللانهائي

قد ترغب في استخدام التحكم اللانهائي في الحالات التالية:

  • لا يمكنك تحديد وقت الانتظار لعملية ما.
  • لا يمكنك اكتشاف تقدم عملية ما.
  • لا تريد الإشارة إلى المدة التي ستستغرقها العملية.

Image title

التحكم المحدد

قد ترغب في استخدام هذا التحكم عندما يمكنك تحديد وقت الانتظار لعملية ما وتريد أن يرى المستخدمون مؤشرًا بناءً على ذلك الوقت.

لعرض تقدم العملية، استخدم خاصية Value لتعيين رقم. لتعيين النسبة المئوية لشريط التقدم، استخدم خصائص Minimum و Maximum.

Image title

يوضح لك كود الإضافة أدناه كيفية إنشاء شريط تقدم باستخدام كل من التحكم اللانهائي والمحدد (الأخضر):

 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
        }
    }        
}

مربعات الحوار

OpenFileDialog و OpenFolderDialog

توفر واجهة برمجة تطبيقات cTrader Algo واجهة OpenFileDialog لتمكين المستخدمين من تحديد ملف لخوارزمية. عندما يحدد المستخدم ملفًا في النافذة الناتجة، يتم نسخ الملف إلى مجلد Selected files الخاص بالخوارزمية. يمكن للخوارزمية العمل مع الملفات داخل مجلد Selected files الخاص بها دون قيود.

نصيحة

استخدم وظيفة OpenFileDialog عندما تحتاج إلى تحميل ملفات بيانات مهمة أو ملفات نسخ احتياطي أو تكوين أو مؤشرات أو نصوص برمجية مخصصة.

يوضح لك الكود أدناه كيفية استخدام مربع حوار OpenFileDialog في مؤشر:

 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

توفر واجهة برمجة تطبيقات cTrader Algo واجهة OpenFolderDialog لتمكين المستخدمين من تحديد مجلد لخوارزمية. عندما يحدد المستخدم مجلدًا في النافذة الناتجة، يتم نسخ جميع الملفات والمجلدات التي تحتوي على ملفات داخل المجلد المحدد إلى مجلد Selected files الخاص بالخوارزمية.

نصيحة

استخدم وظيفة OpenFolderDialog عندما تحتاج إلى تحميل مجلد يحتوي على ملفات بيانات حيوية أو ملفات نسخ احتياطي أو تكوين أو مؤشرات أو نصوص برمجية مخصصة.

عادةً ما يتم نسخ الملفات والمجلدات المحددة إلى مجلد Selected files لأن الخوارزمية يمكنها العمل مع العناصر داخل هذا المجلد حتى عندما يتم تعيين AccessRights الخاص بها إلى None.

ملاحظة

عادةً ما يكون مجلد Selected files الخاص بالخوارزمية على طول هذا المسار: ..\Documents\cAlgo\Data\{AlgoType}\{AlgoName}\Selected files\

يختلف مجلد Selected files لنسخة خوارزمية cBot عن المسار أعلاه: ..\Documents\cAlgo\Data\cBots\{cBotName}\{Instance-Id}\Selected files\

يوضح لك الكود أدناه كيفية استخدام مربع حوار OpenFolderDialog في مؤشر:

 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

توفر واجهة برمجة تطبيقات cTrader Algo واجهة SaveFileDialog لتمكين المستخدمين من حفظ الملفات (محليًا) على أجهزة الكمبيوتر الخاصة بهم. عندما تظهر النافذة ذات الصلة، يحدد المستخدم المجلد الذي يريد حفظ الملف فيه ويدخل اسمًا للملف. ثم يتم حفظ الملف في الموقع المحدد.

نصيحة

استخدم وظيفة SaveFileDialog عندما تحتاج إلى القيام بأي مما يلي:

  • حفظ تقارير الأداء أو نتائج الاختبار العكسي أو ملفات التكوين أو بيانات التحسين.
  • تصدير سجلات التداول أو سجلات العمليات أو بيانات نشاط المستخدم العامة.
  • تخزين المؤشرات المخصصة أو البيانات للرسوم البيانية والتصورات أو معلمات الاستراتيجية.

يوضح لك الكود أدناه كيفية استخدام مربع حوار SaveFileDialog في مؤشر:

 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)
        {
        }
    }
}

عناصر التحكم القابلة للسحب

عنصر التحكم القابل للسحب في منطقة الرسم البياني

توفر واجهات ChartDraggable وChartDraggables أنواعًا تسمح لك بإضافة عنصر تحكم قابل للسحب قادر على استضافة عناصر تحكم أخرى وعناصر مختلفة إلى الرسم البياني. تجعل عناصر التحكم القابلة للسحب هذه من السهل على المستخدمين التفاعل مع عناصر الرسم البياني المختلفة.

ملاحظة

يمكن تحريك أو إعادة تموضع عنصر التحكم القابل للسحب فقط داخل الرسم البياني الذي تمت إضافته إليه.

يوضح هذا الكود كيفية إنشاء مؤشر يضيف عنصري تحكم يمكن تحريكهما داخل الرسم البياني:

 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})");
        }
    }
}

عنصر التحكم القابل للسحب في نافذة التطبيق

توفر واجهات ApplicationDraggable وApplicationDraggables الأنواع المستخدمة لإضافة عناصر تحكم عائمة يمكن تحريكها بشكل فردي عبر نافذة تطبيق cTrader بأكملها. تمكّن مثل هذه العناصر من إنشاء واجهات مستخدم تفاعلية وديناميكية.

ملاحظة

من بين الأنواع الثلاثة للخوارزميات، يُسمح فقط للإضافات بتنفيذ عناصر تحكم قابلة للسحب على مستوى التطبيق بأكمله.

يوضح هذا الكود كيفية إنشاء إضافة تضيف مكون WebView وكتلة نصية في نافذتين منفصلتين، يمكن تحريكهما عبر واجهة مستخدم 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;
        }
    }
}

عنصر التحكم في علامات التبويب

توفر فئة TabControl أنواعًا تسمح لك بإنشاء علامات تبويب متعددة للخوارزمية. يمكن استخدام علامات التبويب هذه للحفاظ على العناصر ذات الصلة معًا أو لعرض طرق عرض منفصلة للوظائف.

يوضح هذا الكود كيفية استخدام علامات التبويب في إضافة تمت إضافتها إلى لوحة الرمز النشط:

 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()
        {
        }
    }
}

عناصر التحكم المخصصة

عنصر التحكم المخصص هو عنصر تحكم يتكون في جوهره من عدة عناصر تحكم محددة مسبقًا. بعبارة أخرى، إنه عنصر تحكم تشكل عناصر التحكم الأخرى محتواه.

تعمل عناصر التحكم المخصصة كفئات قابلة لإعادة الاستخدام بشكل مماثل لعناصر التحكم المدمجة.

 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);
        }
    }
}

يجب أن يعرض مثيل هذا المؤشر أربعة مربعات نصية مباشرة في وسط الرسم البياني الرئيسي.

تنظيم عناصر التحكم باستخدام اللوحات

لجعل العمل مع عناصر التحكم أكثر ملاءمة، قد ترغب في وضع العديد من عناصر التحكم في مجموعة متميزة لها موقعها الخاص في واجهة المستخدم. للقيام بذلك، يمكنك استخدام فئة Panels ومشتقاتها.

فكر في اللوحة كعنصر تحكم يحتوي على عناصر تحكم أخرى كمحتوياته. يدعم cTrader خمس فئات مختلفة ترث من الفئة الأساسية Panels (والتي ترث بدورها من فئة Control):

  • Canvas
  • DockPanel
  • Grid
  • StackPanel
  • WrapPanel

تستخدم كل من الفئات المذكورة أعلاه تخطيطات لوحات مختلفة واستراتيجيات تموضع كما هو موضح أدناه.

اللوحة القماشية

اللوحة القماشية هي لوحة تسمح بتموضع عناصر التحكم بناءً على إحداثيات X و Y معينة.

من الجدير بالذكر أن محوري X و Y مختلفان عن تلك المستخدمة من قبل كائنات الرسم البياني أو الرسومات. تمثل إحداثيات X و Y المستخدمة بواسطة فئة Canvas قيمًا رقمية تبدأ من (0، 0) من الزاوية العلوية اليسرى للرسم البياني.

انظر إلى المثال التالي:

 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)
        {
        }
    }
}

عند إنشاء مثيل للمؤشر أعلاه، يجب أن ترى زر انقر هنا في الزاوية العلوية اليسرى من الرسم البياني.

تحدد خاصية Top لعنصر التحكم موضعه على المحور Y. بدوره، تحدد خاصية Left موضعه على المحور X.

يستخدم الكود أعلاه أيضًا خصائص Padding وMargin. تشير Padding إلى المسافة بين محتويات عنصر التحكم وحدوده الخارجية. Margin هي المسافة بين عنصر التحكم وحدود العنصر الأصلي له. تنطبق خصائص Padding وMargin على جميع اللوحات، وليس فقط على فئة اللوحة القماشية. إنها مفيدة لإدارة المسافات بين عناصر التحكم الخاصة بك.

في معظم الحالات، يتم استخدام فئة Canvas لتجميع عدد صغير فقط من عناصر التحكم.

لوحة الإرساء

تُستخدم فئة DockPanel لإرساء (وضع) عنصر تحكم في موقع ثابت على الرسم البياني. هناك أربعة مواضع إرساء ممكنة:

  • أعلى
  • أسفل
  • يسار
  • يمين

لكل عنصر تحكم خاصية Dock. عند استخدام فئة DockPanel، يمكنك استخدام هذه الخاصية لتموضع عنصر تحكم داخل DockPanel. يتم توضيح ذلك في المثال التالي:

 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)
        {
        }
    }
}

عند إنشاء مثيل لهذا المؤشر، يجب أن ترى لوحة إرساء في وسط الرسم البياني تحتوي على حقل نصي وزر قابل للنقر.

لاحظ أنه يمكن ملء لوحات الإرساء إما أفقيًا أو عموديًا. لا يمكنك استخدام كلا هذين الاتجاهين في نفس الوقت. يتم تعيين اتجاه لوحة الإرساء تلقائيًا عند إعداد أول عنصر تحكم في DockPanel. إذا تم تعيين خاصية Dock لعنصر التحكم الأول إلى Top أو Bottom، فسيتم توجيه DockPanel بأكمله عموديًا، والعكس صحيح.

لوحة التكديس

لوحات التكديس هي واحدة من عناصر التحكم الأكثر استخدامًا بسبب بساطتها وسهولة استخدامها. تقوم لوحات التكديس بمحاذاة عناصر التحكم الفرعية إما أفقيًا أو عموديًا واحدًا تلو الآخر. كما هو موضح أدناه، عليك فقط إعداد اتجاهها وستتولى الفئة إدارة الباقي:

 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)
        {
        }
    }
}

بعد إنشاء مثيل للمؤشر، يجب أن ترى لوحة تكديس أفقية بها حقلان نصيان وزر 'إرسال' في الزاوية السفلية اليمنى من الرسم البياني الرئيسي.

لوحة الالتفاف

لوحات الالتفاف متطابقة في معظمها مع لوحات التكديس. ومع ذلك، عندما لا يكون هناك مساحة كافية لاحتواء جميع عناصر لوحة الالتفاف، فإنها ستقوم تلقائيًا بالتفاف العناصر المتبقية إلى السطر التالي على المحور Y.

الشبكة

فكر في الشبكات كجداول بيانات بعدد محدد من الأعمدة والصفوف. عند استخدام الشبكات، يمكنك إضافة عناصر تحكم إلى كل خلية منفصلة.

كما هو موضح أدناه، عندما تقوم بإنشاء مثيل لفئة Grid، فإنك تمرر عدد صفوفها وأعمدتها كوسائط integer. عند إضافة عناصر أو عناصر تحكم جديدة، يجب عليك بالمثل تحديد عدد الصفوف والأعمدة الفرعية.

 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)
        {
        }
    }
}

عند إنشاء مثيل للمؤشر أعلاه، يجب أن ترى شبكة 10×2 في وسط الرسم البياني.

التحكم في الموضع ضمن إحداثيات السعر والوقت

بالإضافة إلى عناصر التحكم في اللوحة، يتيح cTrader تحديد إحداثيات السعر والوقت لعناصر التحكم مباشرة في منطقة الرسم البياني. توفر طرق AddControl() و MoveControl() هذه الوظيفة لمطوري الخوارزميات.

استخدم التحميلات الزائدة التالية للطريقة لإدارة إحداثيات عناصر التحكم في الرسم البياني حسب تفضيلاتك.

لإضافة عنصر تحكم في الرسم البياني إلى منطقة الرسم البياني أو المؤشر على إحداثيات الفهرس المطلق للشريط والسعر (س، ص).

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

لنقل عنصر تحكم في الرسم البياني إلى منطقة الرسم البياني أو المؤشر على إحداثيات الفهرس المطلق للشريط والسعر (س، ص).

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

لإضافة عنصر تحكم في الرسم البياني إلى منطقة الرسم البياني أو المؤشر على إحداثيات الوقت المطلق والسعر (س، ص).

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

لنقل عنصر تحكم في الرسم البياني إلى منطقة الرسم البياني أو المؤشر على إحداثيات الوقت المطلق والسعر (س، ص).

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

لإضافة عنصر تحكم في الرسم البياني إلى منطقة الرسم البياني أو المؤشر على إحداثية الوقت المطلق (س).

1
void AddControl(ControlBase control, DateTime time)

لنقل عنصر تحكم في الرسم البياني إلى منطقة الرسم البياني أو المؤشر على إحداثية الوقت المطلق (س).

1
void MoveControl(ControlBase control, DateTime time)

لإضافة عنصر تحكم في الرسم البياني إلى منطقة الرسم البياني أو المؤشر على إحداثية الفهرس المطلق للشريط (س).

1
void AddControl(ControlBase control, int barIndex)

لنقل عنصر تحكم في الرسم البياني إلى منطقة الرسم البياني أو المؤشر على إحداثية الفهرس المطلق للشريط (س).

1
void MoveControl(ControlBase control, int barIndex)

لإضافة عنصر تحكم في الرسم البياني إلى منطقة الرسم البياني أو المؤشر على إحداثية السعر المطلق (ص).

1
void AddControl(ControlBase control, double y)

لنقل عنصر تحكم في الرسم البياني إلى منطقة الرسم البياني أو المؤشر على إحداثية السعر المطلق (ص).

1
void MoveControl(ControlBase control, double y)

يمكن أن تتضمن فئة المعلمة ControlBase أي فئة فرعية أخرى (Control، Button، إلخ) لاستدعاء الطريقة وفقًا للتوقيعات المذكورة أعلاه.

يضيف مثال cBot التالي زر انقر هنا! فوق الشريط الأخير على الرسم البياني. يتم نقل الزر إلى الأمام مع كل شريط جديد يتم إضافته. بعد النقر على الزر، يظهر مربع رسالة على الشاشة.

 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");
        }
    }
}

تحذير

يقتصر عدد عناصر التحكم الأساسية التي يمكن إضافتها إلى الرسم البياني على 100 بسبب مشكلات الأداء المحتملة. ينطبق هذا القيد فقط على مثيل واحد للخوارزمية وعناصر التحكم المرتبطة بالسعر والأشرطة.

خصائص التباعد والهامش

تحدد خاصية Margin المسافة بين حدود كائن Control والعنصر الأصلي له (رسم بياني، لوحة، حد، إلخ).

بدورها، تحدد خاصية Padding المسافة بين محتويات عنصر التحكم وحدوده. يمكنك تغيير قيم الخاصية بحيث تكون مختلفة لجميع الجوانب المختلفة.

 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)
        {
        }
    }
}

سينشئ مثيل هذا المؤشر زر انقر هنا رمادي اللون في الزاوية العلوية اليسرى من الرسم البياني. قم بتعديل المعلمات في نوافذ إضافة مثيل أو تعديل المعلمات لترى بالضبط كيف تغير قيم الهامش والتباعد المختلفة كيفية عرض عنصر التحكم.

الأنماط

عند استخدام الأنماط، يمكنك إعطاء مظهر مماثل لعدة أنواع مختلفة من عناصر التحكم. هذا مفيد بشكل خاص عند التعامل مع عدد كبير (خمسة أو أكثر) من عناصر التحكم.

تتيح فئة Style تعيين قيم لخصائص مختلفة لعناصر التحكم مثل Margin أو BackgroundColor. بعد ذلك، يمكنك إعادة استخدام هذه القيم كقالب للعديد من عناصر التحكم الأخرى.

يمكننا أيضًا إنشاء مظهر متناسق لعناصر تحكم متعددة دون استخدام فئة Style على الإطلاق.

 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)
        {
        }
    }
}

إليك كيف يمكن أن يبسط استخدام فئة Style العمل مع عناصر تحكم متعددة.

 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)
        {
        }
    }
}

يجب أن تعرض مقتطفات الشفرة أعلاه نفس عناصر التحكم إذا قمت بتشغيل مثيلات المؤشر الخاصة بها.

يمكنك أيضًا استخدام فئة Style لتغيير مظهر عنصر التحكم بناءً على حالته.

 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)
        {
        }
    }
}

الصورة

يمكن استخدام عنصر التحكم Image لعرض صورة مخزنة محليًا. يستخدم عنصر التحكم Image فئة Bitmap الخاصة بـ .NET، مما يعني أنه يدعم غالبية تنسيقات الصور الشائعة مثل ما يلي:

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

راجع وثائق فئة Bitmap الخاصة بـ .NET لمعرفة المزيد عنها.

لاستخدام عنصر التحكم Image، قم بتعيين خاصية Source الخاصة به إلى بيانات ملف الصورة في مصفوفة بايت (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)
        {
        }
    }
}

بعد تشغيل مثيل للمؤشر أعلاه، يجب ألا ترى أي شيء جديد على الرسم البياني الرئيسي. ومع ذلك، أدخل مسار ملف صالح كقيمة لمعلمة (مسار ملف الصورة)، ويجب أن ترى الصورة المختارة معروضة في وسط الشاشة.

يمكنك أيضًا استخدام موارد مشروعك لتخزين الصور وعرضها عبر عنصر التحكم Image. للقيام بذلك، افتح موارد المشروع في Visual Studio وانتقل إلى علامة التبويب الموارد. فيها، قم بإنشاء مورد جديد وأضف صورة موجودة. بعد ذلك، ستتمكن من استخدام هذه الصورة كمصدر في أي عنصر تحكم Image عبر خاصية Project_Name_Space.Properties.Resources._Image_Name.

كمثال، انسخ الصورة أدناه واحفظها باسم "image.png" على نظامك:

Image title

قم بإنشاء مؤشر جديد في cTrader، وقم بتعيين اسمه إلى "Image Sample"، وافتحه عبر Visual Studio. بعد ذلك، أضف مؤشر الشعار كمورد للمشروع. للقيام بذلك، انقر بزر الماوس الأيمن على مشروعك، وحدد خصائص وانقر على موارد، ثم انقر على إنشاء وإدارة موارد التجميع. انسخ ملف logo.png إلى علامة التبويب التي تم فتحها حديثًا.

انسخ الشفرة أدناه إلى ملف الشفرة المصدر الرئيسي للمؤشر الخاص بك:

 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)
        {
        }
    }
}

بعد إنشاء مثيل لهذا المؤشر، يجب أن ترى الإخراج التالي.

Image title

ملاحظة

الحجم الأقصى للصور هو 10 ميجابايت.