Ответы пользователя по тегу Windows Forms
  • Как извлечь и обработать данные из запускающего файла собственного расширения?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Прочитать из аргументов командной строки, примерно так:
    static class Program
    {    
      [STAThread]
      static void Main(string[] args) // <---
      {
        // args - будет содержать параметры запуска программы
      }
    }

    либо:

    string[] args = Environment.GetCommandLineArgs();
    Ответ написан
    1 комментарий
  • Где можна подучить дизайн в Windows Form?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    FlowLayoutPanel и TableLayoutPanel - вот и весь дизайн :-)

    5b3601df55816684367353.png
    Ответ написан
    Комментировать
  • Как изменить textbox формы из другого класса?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    private void Cl_SendMessage(string mess)
    {
        // если метод вызывается не из потока, к которому привязана форма
        // https://msdn.microsoft.com/ru-ru/library/system.windows.forms.control.invokerequired.aspx
        if (this.InvokeRequired)
        {
          // делаем вызов из потока формы
          // https://msdn.microsoft.com/ru-ru/library/zyzhdc6b.aspx
          this.Invoke(new Action<string>(this.Cl_SendMessage), mess);
          // уходим из этого метода
          return;
          // или можно в условии сделать else
          // кому как больше нравится
        }
        // else {
    
        // код находящийся здесь будет выполняться только если 
        // текущий поток - это поток в котором находится форма
        chatLogTB.Text += mess;
    
       // }
    }
    Ответ написан
    8 комментариев
  • Как сделать все ячейки равных размеров в tableLayoutPanel WinForms?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Указать размер в процентах, если размер должен изменяться в зависимости от размера формы.
    Либо указать точный размер в пикселях.

    Если требуются разные размеры для разных колонок/строк, то этого можно достичь с использованием вложенных TableLayoutPanel.

    Для выравнивания можно использовать колонки/строки с размером 100%. Примерно как в HTML.

    Вот пример формы для программного генерирования TableLayoutPanel с добавлением колонок и строк одинакового размера (этот код можно просто вставить в Form1):
    public partial class Form1 : Form
    {
    
      private Panel TableContainer = new Panel();
      private NumericUpDown Columns = new NumericUpDown();
      private NumericUpDown Rows = new NumericUpDown();
    
      public Form1()
      {
        InitializeComponent();
    
        this.Width = 420;
          
        var flowLayoutPanel = new FlowLayoutPanel();
        var LabelColumns = new Label();
        var LabelRows = new Label();
        var Create = new Button();
    
        // панель для редактора таблицы
        flowLayoutPanel.SuspendLayout();
        flowLayoutPanel.AutoSize = true;
        flowLayoutPanel.Controls.Add(LabelColumns);
        flowLayoutPanel.Controls.Add(Columns);
        flowLayoutPanel.Controls.Add(LabelRows);
        flowLayoutPanel.Controls.Add(Rows);
        flowLayoutPanel.Controls.Add(Create);
        flowLayoutPanel.Dock = DockStyle.Top;
        flowLayoutPanel.Location = new Point(0, 0);
    
        LabelColumns.AutoSize = true;
        LabelColumns.Dock = DockStyle.Fill;
        LabelColumns.ImageAlign = ContentAlignment.MiddleLeft;
        LabelColumns.Location = new Point(3, 0);
        LabelColumns.Size = new System.Drawing.Size(53, 29);
        LabelColumns.Text = "Колонок:";
        LabelColumns.TextAlign = ContentAlignment.MiddleLeft;
    
        LabelRows.AutoSize = true;
        LabelRows.Dock = DockStyle.Fill;
        LabelRows.Location = new Point(117, 0);
        LabelRows.Size = new Size(40, 29);
        LabelRows.Text = "Строк:";
        LabelRows.TextAlign = ContentAlignment.MiddleLeft;
    
        Columns.Dock = DockStyle.Fill;
        Columns.Location = new Point(62, 3);
        Columns.Minimum = 1;
        Columns.Size = new System.Drawing.Size(49, 20);
        Columns.Value = 3;
    
        Rows.Dock = DockStyle.Fill;
        Rows.Location = new Point(163, 3);
        Rows.Minimum = 1;
        Rows.Size = new Size(49, 20);
        Rows.Value = 2;
    
        Create.AutoSize = true;
        Create.Dock = DockStyle.Left;
        Create.Location = new Point(218, 3);
        Create.Size = new Size(75, 23);
        Create.Text = "Создать";
        Create.UseVisualStyleBackColor = true;
        Create.Click += new System.EventHandler(CreateTable);
    
        // контейнер для вывода готовой таблицы
        TableContainer.Dock = DockStyle.Fill;
          
        // добавляем необходимые элементы на форму
        this.Controls.Add(flowLayoutPanel);
        this.Controls.Add(TableContainer);
    
        this.Controls.SetChildIndex(flowLayoutPanel, 1);
        this.Controls.SetChildIndex(TableContainer, 0);
      }
    
      private void CreateTable(object sender, EventArgs e)
      {
        // удаляем предыдущую таблицу
        TableContainer.Controls.Clear();
    
        // создаем новую
        var tableLayoutPanel = new TableLayoutPanel();
        tableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
        tableLayoutPanel.Location = new System.Drawing.Point(0, 0);
        tableLayoutPanel.Visible = true;
    
        tableLayoutPanel.ColumnCount = Convert.ToInt32(Columns.Value);
        tableLayoutPanel.RowCount = Convert.ToInt32(Rows.Value);
    
        // генератор случайных чисел для раскраски панелей (чтобы было видно)
        var rnd = new Random(DateTime.Now.Millisecond);
    
        // определяем размер одной колонки и строки, в процентах
        int width = 100 / tableLayoutPanel.ColumnCount;
        int height = 100 / tableLayoutPanel.RowCount;
    
        this.Text = String.Format("{0}x{1}", width, height);
    
        // добавляем колонки и строки
        for (int col = 0; col < tableLayoutPanel.ColumnCount; col++)
        {
          // добавляем колонку
          tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, width));
    
          for (int row = 0; row < tableLayoutPanel.RowCount; row++)
          {
            // добавляем строку
            if (col == 0) 
            {
              tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, height));
            }
    
            // добавляем цветную панель, чтобы было видно ячейку в таблице
            var panel = new Panel();
            panel.BackColor = Color.FromArgb(rnd.Next(0, 255), rnd.Next(0, 255), rnd.Next(0, 255));
            panel.Dock = DockStyle.Fill;
            tableLayoutPanel.Controls.Add(panel, col, row);
          }
        }
    
        // добавляем таблицу в контейнер
        TableContainer.Controls.Add(tableLayoutPanel);
      }
    
    
    }

    2ff063c8d06f474da07fa7df6c515be8.gif
    Ответ написан
  • Как в RichTextBox игнорировать/блокировать режим "замена" через insert?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Добавить к экземпляру richTextBox обработчик события KeyDown и отменить нажатие Insert:
    private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
    {
      if (e.KeyCode == Keys.Insert)
      {
        e.Handled = true;
        return;
      }
    }
    Ответ написан
  • Как восстановить в окне конструктора случайно удаленный контрол в winforms?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    С Windows Forms нужно быть готовым к разного рода фокусам со стороны Visual Studio.
    Даже при использовании систем контроля версий, порой приходится повозиться с подлянками в виде пропавших картинок или дочерних элементов в каком-нибудь меню или ToolStrip. Многие подобные случаи можно поправить руками, путем ручного исправления файлов Designer, но не всегда. Чем сложнее форма, тем выше риск того, что дизайнер студии что-нибудь сломает; всегда нужно быть к этому готовым.

    1. Раз появился такой вопрос, то видимо Ctrl + Z точно уже не поможет. Это первое, что нужно было сделать.

    2. Если форма не была сохранения, то для отката изменений можно было бы её просто закрыть без сохранения. Но опять же, это нужно было делать сразу, при возникновении проблемы и если обычный откат назад (Ctrl + Z) не помог.

    3. Если не используется система контроля версий, то нужно регулярно делать резервные копии исходного кода. Использование системам контроля версий будет удобней. Но даже при использовании систем контроля версий, следует регулярно делать резервные копии, и резервные копии резервных копий.

    4. Если есть сборка нужного состояния программы (или приблизительно этому состоянию) и над пропавшим интерфейсом велась работа в поте лица, без перерывов на обед и сон, и все очень сложно и не хочется повторять этот героический поступок, то можно декомпилирвать предыдущую сборку и выдернуть код описания интерфейса из нее. Например, при помощи dotPeek.

    Описание элементов формы, по умолчанию, находятся в файлах Designer. Например, элементы Form1 можно найти в файле Form1.Designer.cs. Иногда у элементов могут просто потеряться ссылки на родителей. Случай случайного удаления элемента и отката назад (Ctrl + Z) как раз-таки может привести к подобному поведению. Код в файле Designer обычно остается и ссылки можно поправить руками. Как правило, речь идет о добавлении строчек кода вида: this.родительскийЭлемент.Controls.Add(this.дочернийЭлемент). Главное понимать, что от чего отвалилось и что к чему нужно привязать. Если не понимать, то можно сделать хуже :-) (не стоит забывать про создание резервных копий). После внесения изменений в код дизайнера, следует переоткрыть конструктор форм (в идеале, перед внесением изменений в *.Designer.cs, конструктор форм (визуальный редактор форм) лучше закрыть).

    Если элемент удален полностью и использовать восстановление из предыдущей сборки, то в декомпилированном коде нужно будет найти класс формы, а в нем метод InitializeComponent. У DataGridView, каждая колонка и строка (при наличии) будут являться отдельными элементами, нужно найти и перенести весь код описания этих элементов. Как правило, для каждого отдельного элемента, установка значений свойствам в коде идет последовательно. Дочерние элементы могут идти в разброс, по именам элементов можно более ли менее понять, что к чему (если стандартные имена у элементов менялись на собственные, то проблем с поиском возникнуть не должно).
    Ответ написан
    Комментировать
  • C# После загрузки картинки в picturebox удалить её с диска?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Работать с файлами лучше через FileStream, чтобы полностью контролировать весь процесс:
    string filePath = "123.jpg";
    
    using (var file = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Inheritable))
    {
      pictureBox1.Image = Image.FromStream(file);
    }
    
    File.Delete(filePath);

    Многие упрощенные методы работы с файлами нередко блокируют доступ к файлам. Такие методы имеет смысл использовать только для одноразовых файловых операций (когда нужно один раз прочитать или записать данные и не более этого).
    Ответ написан
    Комментировать