Ответы пользователя по тегу Программирование
  • Как работать с ценами в разной валюте?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Хранить значения в одной (универсальной) валюте. С сортировкой проблем быть не должно. Что касается фильтрации, то просто конвертировать значение фильтра в универсальную валюту.

    Например, цены хранятся в долларах США. Клиент хочет посмотреть цены от 100 рублей, тогда 100 рублей нужно конвертировать в доллары США и подставить это значение в запрос на выборку.

    При выводе можно конвертировать на лету, выводиться ведь будет немного записей. В крайнем случае, если будут проблемы с производительностью, можно кешировать.
    Ответ написан
    Комментировать
  • Как научиться писать код быстро?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Методика есть и она стара как мир:

    Семь раз подумай, один раз напиши.
    Чем меньше напишешь, тем меньше будет работы.

    А каким образом осуществлять мыслительный процесс - это вам виднее :-)

    Учитесь выносить обдумывание на задний план, так сказать в фоновый режим, чтобы мозг сам думал, а вы могли заниматься чем-то другим. В особенности это касается сложных задач. Сложные задачи где-то в глубинах мозга решаются быстрее. Каким образом развивать этот навык, не могу точно сказать, все само как-то получается. Но однозначно можно утверждать, что нужно чаще думать :-)

    Что касается механики, то быстро вводить код - это не то, к чему стоит стремиться, конечно если целью не является желание стать секретаршей :-)
    Ответ написан
    5 комментариев
  • Как найти одинаковые элементы массива объектов (в 1 массиве)?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Собрать коллекцию, примерно так:
    var result = new Dictionary<int, List<object>>();
    
    foreach (var item in arrComputer)
    {
      var c = (Comp)item;
      // проверяем, есть такой год в коллекции или нет
      if (!result.ContainsKey(c.year))
      {
        // такого года еще нет, добавляем
        result.Add(c.year, new List<object> { c });
      }
      else
      {
        // год есть, добавляем запись в него
        result[c.year].Add(c);
      }
    }
    
    // в result будет коллекция: год-компьютеры
    foreach (int year in result.Keys)
    {
      Console.WriteLine
      (
        "В {0} году на Земле вылупилось компьютеров: {1}", 
        year, 
        result[year].Count
      );
    
      if (result[year].Count > 1)
      {
        Console.WriteLine("Да это просто демографический взрыв какой-то!");
        foreach (var item in result[year])
        {
          Console.WriteLine("+ {0}", ((Comp)item).marka);
        }
      }
    }

    Вместо object можно сразу использовать Comp, если использование других типов не предполагается.
    Ответ написан
    Комментировать
  • C#. Как вызвать балуна из трея?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Разместить на форме компонент NotifyIcon, если используется проект Windows Forms.

    Для вывода уведомления, использовать метод NotifyIcon.ShowBalloonTip:

    // необходимо обязательно указать иконку
    // иначе уведомление не будет отображаться
    // можно использовать иконку формы
    notifyIcon1.Icon = this.Icon;
    
    // показываем уведомление
    notifyIcon1.ShowBalloonTip(
      10000, 
      "Новый ответ", 
      "Поступил новый ответ на ваш вопрос на Toster.ru",
      ToolTipIcon.Info
    );
    
    // или с текстом по умолчанию (см. BalloonTipTitle, BalloonTipText)
    // notifyIcon1.ShowBalloonTip(10000);

    Окно программы может находиться в любом состоянии.

    В проектах отличных от Windows Forms можно подключить сборку System.Windows.Forms, но лучше разобраться, может быть есть более правильно решение. Например, для консольных приложений такое решение вполне годится.
    Ответ написан
    3 комментария
  • Что такое библиотека кода?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    "Библиотека кода" - в программировании такого термина я не встречал :-)

    На сайтах для программистов могут быть разделы - библиотеки кода, которые являются просто свалкой кода (примеров кода) для решения разнообразных задач :-)

    Если имеется ввиду библиотека классов (или просто библиотека - англ. library), то это набор классов/модулей/компонентов для выполнения конкретных задач.

    В случае с CSS и HTML, которые упомянуты в тегах этого вопроса, библиотекой можно назвать набор готовых решений, типа Bootstrap (хотя это framework, который состоит из библиотек), Bourbon.

    Основное преимущество библиотек - это переносимость, возможность использовать в разных проектах, отсутствие необходимости вникать в принципы работы.

    При возникновении ошибок в коде библиотеки или добавлении улучшений, новых функций/возможностей, достаточно будет выпустить (или получить, смотря с какой стороны смотреть) новую версию. Это проще, чем держать однотипный код, одинаковые решения в разных проектах и потом из-за досадной опечатки сидеть и перелопачивать все :-) Использование библиотек экономит время.
    Ответ написан
    Комментировать
  • Как в родительской форме перехватить закрытие дочерней?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Просто обработчик события закрытия формы добавить:
    var f = new Form2();
    f.Owner = this;
    
    f.FormClosed += (object s, FormClosedEventArgs args) =>
    {
      MessageBox.Show("Форма закрыта!");
    };
    
    f.Show();

    Либо так:
    private void button1_Click(object sender, EventArgs e)
    {
      var f = new Form2();
      f.Owner = this;
    
      f.FormClosed += Form2_FormClosed;
    
      f.Show();
    }
    
    private void Form2_FormClosed(object sender, FormClosedEventArgs e)
    {
      MessageBox.Show("Форма закрыта!");
    }

    Еще можно показать дочернюю форму как диалог (для контейнера Mdi не подойдет):
    var f = new Form2();
    f.Owner = this;
    // главная форма будет недоступна
    f.ShowDialog();
    // после закрытия диалоговой формы, выполнение продолжится
    MessageBox.Show("Форма закрыта!");
    Ответ написан
    Комментировать
  • Как вызвать хранимую процедуру из приложения?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    dataAdapter = new SqlDataAdapter("Имя процедуры", connectionString);
    dataAdapter.SelectCommand.CommandType = CommandType.StoredProcedure;

    Либо с использованием SqlCommand:
    var connection = new SqlConnection(connectionString);
    // connection.Open();
    var cmd = new SqlCommand("Имя процедуры", connection);
    cmd.CommandType = CommandType.StoredProcedure;
    dataAdapter = new SqlDataAdapter(cmd);
    Ответ написан
    Комментировать
  • C# checkbox .Checked xaml?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Checked - это событие.

    Состояние можно задать свойством IsChecked:
    CheckBox cb = (CheckBox)sender;
    cb.IsChecked = true;
    Ответ написан
    1 комментарий
  • 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);

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

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    
    namespace WindowsFormsApplication9
    {
      public partial class Form1 : Form
      {
    
        /// <summary>
        /// Получает текущее положение ползунка полосы прокрутки.
        /// </summary>
        /// <param name="hWnd">Дескриптор.</param>
        /// <param name="nBar">Тип.</param>
        /// <returns></returns>
        [DllImport("User32.dll")]
        public extern static int GetScrollPos(IntPtr hWnd, int nBar);
    
        /// <summary>
        /// Функция для отправки сообщений.
        /// </summary>
        /// <param name="hWnd">Дескриптор.</param>
        /// <param name="msg">Само сообщение.</param>
        /// <param name="wParam">Параметры.</param>
        /// <param name="lParam">Дополнительные параметры.</param>
        [DllImport("User32.dll")]
        public extern static int SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
    
        public enum ScrollBarType : uint
        {
          SbHorz = 0,
          SbVert = 1,
          SbCtl = 2,
          SbBoth = 3
        }
    
        public enum Message : uint
        {
          /// <summary>
          /// Сообщение для вертикальной полосы прокрутки
          /// </summary>
          WM_VSCROLL = 0x0115
        }
    
        public enum ScrollBarCommands : uint
        {
          /// <summary>
          /// Положение ползунка полосы прокрутки в конце операции
          /// </summary>
          SB_THUMBPOSITION = 4
        }
    
        private RichTextBox rich1 = new RichTextBox();
        private RichTextBox rich2 = new RichTextBox();
    
    
        public Form1()
        {
          InitializeComponent();
    
          // тестовый текст
          string text = "";
          for (int i = 0; i < 99; i++)
          {
            text += "Имеется 2 richTextBox, нужно установить значение текущего вертикального скролла первого, как у в данный момент у второго. Пробовал всякие offset, копался в гугле, но ничего внятного не нашел.\r\n";
          }
    
          // добавляем поля на форму
          rich1.Name = "rich1";
          rich1.Dock = DockStyle.Top;
          rich1.Text = text;
          rich1.VScroll += rich_VScroll;
          this.Controls.Add(rich1);
    
          rich2.Name = "rich2";
          rich2.Dock = DockStyle.Top;
          rich2.Text = text;
          rich2.VScroll += rich_VScroll;
          this.Controls.Add(rich2);
        }
    
        /// <summary>
        /// Обработчик изменения положения ползунка полосы прокрутки.
        /// </summary>
        private void rich_VScroll(object sender, EventArgs e)
        {
          // кто вызвал событие
          RichTextBox currentRich = (RichTextBox)sender;
          // если событие вызвал rich2, то второй будет rich1 и наоборот
          RichTextBox otherRich = currentRich.Name.Equals("rich1") ? rich2 : rich1;
    
          // получаем позицию ползунка полосы прокрутки текущего поля
          int pos = GetScrollPos(currentRich.Handle, (int)ScrollBarType.SbVert);
          pos <<= 16;
    
          // чтобы не застрять в бесконечности 
          // (можно так не делать и прикрутить обработчик только к одному полю)
          otherRich.VScroll -= rich_VScroll; 
          // --
    
          // передаем позицию во второе поле
          uint par = (uint)ScrollBarCommands.SB_THUMBPOSITION | (uint)pos;
          SendMessage(otherRich.Handle, (int)Message.WM_VSCROLL, new IntPtr(par), new IntPtr(0));
          otherRich.VScroll += rich_VScroll;
        }
      }
    }
    Ответ написан
    2 комментария
  • Приложение не запускается на WinXP, как можно исправить?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    На Windows XP должен быть установлен .NET Framework. В данном случае, версия 2.0. Также может потребоваться Service Pack 3.

    Лучше ниже .NET Framework 3.5 не использовать.
    И .NET Framework 4.0 под Windows XP вполне нормально работает, если установить. Версия 4.5 уже не поддерживается

    .NET 2.0, если не изменяет память, по умолчанию не входил в состав Windows XP (если хотелось именно этого).
    Ответ написан
    2 комментария
  • Как повторить текущую итерацию while C#?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Зависит от логики. Если, как показано ниже, то можно использовать continue:
    int i = 0;
    bool b = false;
    while (i < 10)
    {
    	Console.WriteLine("Текущее: {0}", i);
    			
    	if (i == 5 && !b)
    	{
    		b = true;
    		continue;
    	}
    			
    	i++;
    }

    В крайнем случае есть goto:
    int i = 0; 
    bool b = false;
    while (i < 10)
    {
    	again: // точка возврата
    	Console.WriteLine("Текущее: {0}", i);
    			
    	if (i == 5 && !b)
    	{
    		b = true;
    		goto again;
    	}
    			
    	i++;
    }

    Посмотреть online-пример

    Однако не следует злоупотреблять подобными переходами. От обилия операторов goto в коде, у программиста может случиться разрыв мозга, что приведет к неминуемой гибели проекта и его возрождению в новом виде, если, конечно, сам программист не скопытится. Травма та серьезная :-) Если есть возможность, желание и время, лучше изменить логику так, чтобы не приходилось делать такие «прыжки».

    Для получения файлов или вообще работы с файлами (ожидание доступа для чтения или удаления, получение данных из сети и т.п.), можно использовать вложенный цикл, который будет пробовать выполнить задачу до тех пор, пока она будет успешно выполнена или не истечет отведенное время на выполнение задачи (или количество попыток):
    // пауза между попытками (100 мс)
    var interval = new TimeSpan(0, 0, 0, 0, 100); 
    // максимальное время ожидания (1 секунда)
    var timeout  = new TimeSpan(0, 0, 0, 1); 
    while (true)
    {
      var totalTime = new TimeSpan(); // счетчик времени
      var заданиеВыполнено = false;
    
      while(!заданиеВыполнено) // повторять, пока задание не будет выполнено
      {
        try
        {
          // тут код задания
          // если ошибок не будет, то
          заданиеВыполнено = true; // работа цикла будет завершена
        }
        catch
        {
          // если ошибка, делаем паузу
          System.Threading.Thread.Sleep(100);
          // увеличиваем счетчик времени
          totalTime += interval;
          if (totalTime > timeout)
          {
    				// превышен таймаут, выходим
    				Console.WriteLine("Превышено время ожидания");
    				break;
          }
        }
      }
    }
    Ответ написан
  • Как сделать так, чтобы после нажатия кнопки можно было щелкнуть мышкой в PictureBox и там бы нарисовался круг?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Фигуры фиксированного размера можно нарисовать так:
    public partial class Form1 : Form
    {
    
        private int BrushType = 1;
    
        public Form1()
        {
          InitializeComponent();
    
          // создаем PictureBox
          var pic = new PictureBox { Dock = DockStyle.Fill, BackColor = Color.White };
          pic.MouseClick += PictureBox_MouseClick;
          this.Controls.Add(pic);
    
          // создаем панель для кнопок
          var panel = new FlowLayoutPanel { Dock = DockStyle.Top, AutoSize = true };
          this.Controls.Add(panel);
    
          // кнопки
          var btn = new RadioButton 
          { 
            Text = "Круг", 
            Tag = 1, 
            Appearance = Appearance.Button, 
            Checked = true, 
            AutoSize = true 
          };
          btn.Click += Button_Click;
          panel.Controls.Add(btn);
    
          btn = new RadioButton
          {
            Text = "Не круг",
            Tag = 2,
            Appearance = Appearance.Button,
            AutoSize = true
          };
          btn.Click += Button_Click;
          panel.Controls.Add(btn);
    
          btn = new RadioButton
          {
            Text = "Квадратный круг",
            Tag = 3,
            Appearance = Appearance.Button,
            AutoSize = true
          };
          btn.Click += Button_Click;
          panel.Controls.Add(btn);
        }
    
        private void Button_Click(object sender, EventArgs e)
        {
          var btn = (RadioButton)sender;
          this.BrushType = (int)btn.Tag;
        }
    
        private void PictureBox_MouseClick(object sender, MouseEventArgs e)
        {
          // получаем ссылку на PictureBox
          var pic = (PictureBox)sender;
          // получаем Graphics из PictureBox
          var g = pic.CreateGraphics();
    
          if (this.BrushType == 2)
          {
            // рисуем не круглый квадрат
            g.DrawRectangle(Pens.Black, e.X, e.Y, 50, 50);
          }
          else if (this.BrushType == 3)
          {
            // рисуем квадратный круг
            Point[] points = new Point[6];
            int half = 50 / 2;
            int quart = 50 / 4;
            points[0] = new Point(e.X + quart, e.Y);
            points[1] = new Point(e.X + 50 - quart, e.Y);
            points[2] = new Point(e.X + 50, e.Y + half);
            points[3] = new Point(e.X + 50 - quart, e.Y + 50);
            points[4] = new Point(e.X + quart, e.Y + 50);
            points[5] = new Point(e.X, e.Y + half);
            g.DrawPolygon(Pens.Black, points);
          }
          else
          {
            // рисуем эллипс
            g.DrawEllipse(Pens.Black, e.X, e.Y, 50, 50);
          }
        }
    
    }

    В качестве кнопок используются RadioButton, т.к. это удобней.
    Чтобы не стиралось, можно сделать Bitmap:
    var pic = (PictureBox)sender;
    if (pic.Image == null) { pic.Image = new Bitmap(pic.Width, pic.Height); }
    var bmp = new Bitmap(pic.Image);
    var g = Graphics.FromImage(bmp);

    И после завершения рисования, передать картинку в PictureBox:
    pic.Image = bmp;

    Результат:
    c141d6f9ebe44712a5d9c5f9aa67dcb1.png
    Ответ написан
    1 комментарий
  • Не работает FindWindow?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    У меня работает:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.InteropServices;
    
    namespace ConsoleApplication13
    {
      class Program
      {
        [DllImportAttribute("User32.dll")]
        private static extern int FindWindow(String ClassName, String WindowName);
    
        [DllImportAttribute("User32.dll")]
        private static extern IntPtr SetForegroundWindow(int hWnd);
    
        static void Main(string[] args)
        {
          int hWnd = FindWindow(null, "Калькулятор");
          Console.WriteLine(hWnd);
          if (hWnd > 0)
          {
            Console.WriteLine("К счастью, окно найдено...");
            SetForegroundWindow(hWnd); 
          }
          else
          {
            Console.WriteLine("Окно не найдено!");
          }
          Console.ReadKey();
        }
      }
    }

    С использованием класса Process, этот код должен активировать все открытые калькуляторы:
    static void Main(string[] args)
    {
      foreach (var p in Process.GetProcessesByName("calc"))
      {
        SetForegroundWindow(p.MainWindowHandle.ToInt32()); 
      }
    
      Console.ReadKey();
    }
    Ответ написан
    2 комментария
  • Почему не работает калькулятор?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Дело в десятичном разделителе:
    string value = textBox1.Text;
    // меняем разделитель на текущий
    value = System.Text.RegularExpressions.Regex.Replace(value, @",|\.", System.Globalization.NumberFormatInfo.CurrentInfo.CurrencyDecimalSeparator);
    // преобразуем строку в число
    var result = double.Parse(value);

    Преобразование типов.
    Ответ написан
    4 комментария
  • Кто полностью изучил книги Дональда Кнута "Искусство программирования"?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Есть как минимум один человек, сам Дональд Кнут :-)
    Ответ написан
    Комментировать
  • С чего начать изучение программирования?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Начинать нужно с того, к чему лежит душа :)

    Помню, я начинал с попыток разработки игр, потом были программки-приколы, бесчисленные блокноты, калькуляторы, графические редакторы и даже попытки сотворить ОС. В общем полный набор начинающего программиста.

    Нужно ставить задачи и искать пути их решения.

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

    Проще всего, наверное будет начать с JavaScript, достаточно открыть блокнот и написать:
    <script>
    alert("Hello, world!");
    </script>

    сохранить файл с расширением .html, открыть в браузере и посмотреть на результат первого шага в программировании :)

    Для разработки приложений под Windows, да простят меня микрософтоненавистники, рекомендую: Visual Studio. По языкам программирования, Visual Basic .NET относительно простой, но своеобразен (имеет смысл его знать). C# чуть сложнее, с JavaScript у них синтаксис похож. Си++ более сложный. На радость микрософтоненавистникам могу еще упомянуть о Java (не путать с JavaScript).
    Ответ написан
    Комментировать
  • Как привести объект к типу выше в древе наследования?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Придется делать конструктор в FileMember, который будет принимать Grid и строить себя на его основе. В этом случае связь с исходным объектом потеряется (если критично).

    Как вариант, можно убрать наследование и сделать в FileMember свойство, принимающее Grid. Будет проще передавать Grid в FileMember :) Но придется изрядно доработать FileMember, чтобы он вел себя как Grid. По сути тупая переадресация будет (но подводные камни исключать нельзя, все может оказаться сложнее).

    В итоге нужно выбрать, что будет проще: копировать исходный Grid в FileMember; или определить все свойства, методы Grid и т.п. в FileMember; или отказаться от идеи передавать Grid, использовать только FileMember, изменить исходную задачу на вариант с более простым решением.
    Ответ написан
    3 комментария