динамическое создание элементов

159
22 декабря 2019, 00:30

поставил себе monodevelop, и, после visual studio с windows forms, gtk для меня как китайская грамота в каких-то случаях)

задача состоит в том, чтобы при нажатии на кнопку создавался новый элемент класса NoteBook с заданными размерами и позицией

на данный момент имеется такой вот обработчик на клац по кнопке:

protected void OnAddColBtnClicked(object sender, EventArgs e) {
    int x, y, z;
    Button AddColBtn = (Button) sender;
    x = 30;
    y = 80;
    z = 10;
    Notebook[] note = new Notebook[z];
    for (int i = 1; i <= 10; i++)
    {
        note[i].SizeRequest();
        note[i].HeightRequest = 300;
        note[i].WidthRequest = 600;
        note[i].SetUposition(x, y);
        x += note[i].WidthRequest + 20;
    }
    if (note[1] != null && note[1].Parent == this)
    {
        this.Add(note[2]);
    }
    else if (note[2] != null && note[2].Parent == this)
    {
        this.Add(note[3]);
    }
    else if (note[3] != null && note[3].Parent == this)
    {
        this.Add(note[4]);
    }
    else if (note[4] != null && note[4].Parent == this)
    {
        this.Add(note[5]);
    }
    else if (note[5] != null && note[5].Parent == this)
    {
        this.Add(note[6]);
    }
    else if (note[6] != null && note[6].Parent == this)
    {
        this.Add(note[7]);
    }
    else if (note[7] != null && note[7].Parent == this)
    {
        this.Add(note[8]);
    }
    else if (note[8] != null && note[8].Parent == this)
    {
        this.Add(note[9]);
    }
    else if (note[9] != null && note[9].Parent == this)
    {
        this.Add(note[10]);
    }
    else 
    {
        this.Add(note[1]);
    }
 }

приложение запускается, но при нажатии на кнопку просто вылетает без какой-либо ошибки, также высвечивается предупреждение о том, что SetUposition устарел

Answer 1

Почему вылетает...

Потому что создание массива, не создает его элементы.

Отличие WinForms от Gtk

В WinForms классы контейнеры(формы, панели и тд.) по умолчанию располагают дочерних в пиксельных координатах. Для простой разметки используется свойство Dock и связанные. Если нужна сложная компоновка дочерних компонентов, то сначала на форму кидается GridLayout и в него кидаются дочерние.

В Gtk идеологически построен, так что использование пиксельных координат считается неверным. Почти каждый контрол является контейнером для разметки. То есть форма не может разместить на себе дочерний элемент в определенной позиции. Если кинуть на форму кнопку она займет все область формы. Если нужна сложная компоновка Gtk предлагает различные контролы контейнеры(VBox, HBox и тд.). Вообще это не маленькая тема лучше вам самому с этим поиграться в дизайнере.

Пример с VBox:
Это пример как идеологически верно работать с конролам в Gtk.

using System;
using Gtk;
public partial class MainWindow : Gtk.Window
{
    private VBox _mainBox;
    public MainWindow() 
        : base(Gtk.WindowType.Toplevel)
    {
        Build();
        _mainBox = new VBox();
        this.Add(_mainBox);
        var button = new Button();
        button.Label = "Click me";
        button.Clicked += Button_Clicked;
        _mainBox.PackStart(button, false, false, 10);
        ShowAll();
    }
    protected void OnDeleteEvent(object sender, DeleteEventArgs a)
    {
        Application.Quit();
        a.RetVal = true;
    }
    void Button_Clicked(object sender, EventArgs e)
    {
        var notebook = new Notebook();
        notebook.AppendPage(new TextView(), new Label("Tab1"));
        notebook.AppendPage(new TextView(), new Label("Tab2"));
        _mainBox.PackStart(notebook, true, true, 5);
        _mainBox.ShowAll();
    }
}

Пример с Fixed:
Если все таки нужно размещать дочерних в пиксельных координатах то для этого есть контейнер Fixed.

using System;
using Gtk;
public partial class MainWindow : Gtk.Window
{
    private VBox _mainBox;
    private Fixed _notebookBox;
    public MainWindow() 
        : base(Gtk.WindowType.Toplevel)
    {
        Build();
        _mainBox = new VBox();
        this.Add(_mainBox);
        var button = new Button();
        button.Label = "Click me";
        button.Clicked += Button_Clicked;
        _mainBox.PackStart(button, false, false, 10);
        _notebookBox = new Fixed();
        _mainBox.PackStart(_notebookBox, true, true, 10);
        ShowAll();
    }
    protected void OnDeleteEvent(object sender, DeleteEventArgs a)
    {
        Application.Quit();
        a.RetVal = true;
    }
    void Button_Clicked(object sender, EventArgs e)
    {
        var notebook = new Notebook();
        notebook.AppendPage(new TextView(), new Label("Tab1"));
        notebook.AppendPage(new TextView(), new Label("Tab2"));
        notebook.WidthRequest = 100;
        notebook.HeightRequest = 100;
        var random = new Random();
        var x = random.Next(_notebookBox.Allocation.Width - notebook.WidthRequest);
        var y = random.Next(_notebookBox.Allocation.Height - notebook.HeightRequest);
        _notebookBox.Put(notebook, x, y);
        _notebookBox.ShowAll();
    }
}
READ ALSO
Обучение CSharp и unity и полный тупизм [закрыт]

Обучение CSharp и unity и полный тупизм [закрыт]

Хотите улучшить этот вопрос? Добавьте больше подробностей и уточните проблему, отредактировав это сообщение

156
Анимация кнопки в Unity2D

Анимация кнопки в Unity2D

Сделал анимацию на кнопку, но не работаетПомогите пожалуйста с данной проблемой, т

136
Обновление DataGrid после изменения в БД

Обновление DataGrid после изменения в БД

Прошу подсказать какая хорошая практика обновления отображения данных в DataGrid после операций с БД (EntityFramework/WPF)Ранее приходилось после каждого...

144
Ошибка Unexpected token &lt; in JSON at position 0. Как решить?

Ошибка Unexpected token < in JSON at position 0. Как решить?

Выдает ошибку при оформлении заказа без регистрации

152