Ответы пользователя по тегу C#
  • Где применяют ASP.net сегодня?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Мне интересно в какой сфере применяют ASP

    ASP - умер, да здравствует ASP.NET! А нет, да здравствует ASP.NET Core! ;-)

    1. Любые проекты. Как правильно большие и сложные. Делать что-то простое смысла нет, для этого можно использовать что-нибудь типа PHP.

    2. Работа есть. Но новичкам нынче придется не сладко. За последние семь лет все сильно усложнилось.

    3. Можно делать все :-) Блоги, формы, порталы, магазины, платежные сервисы, корпоративные сайты. В общем, все что угодно. Мои нынешние проекты являются сложными системами, которые я уже не способен охватывать целиком и они не ограничиваются использованием ASP.NET. Но .NET доминирует, поскольку это удобно и работать просто приятно, от процесса написания кода, до отладки и тестирования.
    Ответ написан
    Комментировать
  • Почему не хочет парсить string(Regex)?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    string pattern = "/(.*?)[\\/]([A-Z]*)(,.)(\".*?\")/gm";

    string pattern = "(.*?)/([A-Z]*)(,|.)(\".*?\")";
    var regex = new Regex(pattern, RegexOptions.Multiline);
    Ответ написан
    Комментировать
  • Сохранения и чтения cookie, из текстового файла в xNet?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Использовать базу данных :-)

    Можно попробовать сериализовать CookieDictionary, но Dictionary видимо намекает, что это будет непросто. Если не получится, то можно попробовать сделать свой, сериализуемый, CookieDictionary и использовать его.

    С JSON наверное проблем будет меньше, по крайней мере обычный Dictionary с помощью Newtonsoft.Json можно без проблем сериализовать/десериализовать.

    Можно попробовать с CookieDictionary, примерно так:

    // получаем json:
    string json = JsonConvert.SerializeObject(cookieDictionary);
    
    // получаем экземпляр CookieDictionary из json:
    var cookieDictionary2 = JsonConvert.DeserializeObject<CookieDictionary>(json);

    Если с сериализацией будут проблемы и при преобразовании экземпляра CookieDictionary в строку на выходе всегда получается строка вида: ключ=значение; ключ=значение, то можно разбить эту строку и получить коллекцию:

    // string cookiesRaw = File.ReadAllText(string.Format("Cookies_{0}.txt", textBox1.Text));
    string cookiesRaw = "ключ1=значение1; ключ2=значение2";
    var cookies = cookiesRaw.Split(';').Select(itm => itm.Split('=')).
                  ToDictionary(k => k[0].Trim(), v => v[1].Trim());

    В переменной cookies будет экземпляр Dictionary, который можно попробовать преобразовать в CookieDictionary (зависит от реализации), либо создать и наполнить экземпляр CookieDictionary.

    httpRequest.Cookies = new CookieDictionary();
    
    foreach(var item in cookies)
    {
      httpRequest.Cookies.Add(item.Key, item.Value);
    }
    Ответ написан
    2 комментария
  • Как в цикле считать XML?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    1. Использовать XML-сериализацию (все данные будут загружены в память).

    Классы
    public class Backup
    {
    
      public Basic Basic { get; set; }
    
      public List<Base> Bases { get; set; }
    
    }
    
    public class Basic
    {
    
      public string Path1C { get; set; }
    
    }
    
    public class Base
    {
    
      [XmlAttribute]
      public string Name { get; set; }
    
      [XmlAttribute]
      public string Mode { get; set; }
    
      [XmlAttribute]
      public string Path { get; set; }
    
    }
    Пример использования
    // из строки
    string source =
    (
      @"<?xml version=""1.0"" encoding=""utf-8"" ?>
      <Backup>
        <Basic>
          <Path1C>\\server\1cv8s.exe</Path1C>
        </Basic>
        <Bases>
          <Base Name=""b1"" MODE=""File"" Path=""\\server\Base\base""/>
          <Base Name=""bas2"" MODE=""Server"" Path=""\\server\db""/>
        </Bases>
      </Backup>"
    );
    
    
    using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(source)))
    {
      var serializer = new XmlSerializer(typeof(Backup));
      var backup = (Backup)serializer.Deserialize(ms);
    
      foreach (var b in backup.Bases)
      {
        Console.WriteLine("Name: {0}", b.Name);
        Console.WriteLine("MODE: {0}", b.Mode);
        Console.WriteLine("Path: {0}", b.Path);
      }
    }

    2. Для чтения небольших файлов можно использовать System.Xml.XmlDocument (все данные будут загружены в память):

    var xml = new XmlDocument();
    
    // из файла:
    // xml.Load("XMLFile1.xml");
    
    // из строки
    xml.LoadXml
    (
      @"<?xml version=""1.0"" encoding=""utf-8"" ?>
      <Backup>
        <Basic>
          <Path1C>\\server\1cv8s.exe</Path1C>
        </Basic>
        <Bases>
          <Base Name=""b1"" MODE=""File"" Path=""\\server\Base\base""/>
          <Base Name=""bas2"" MODE=""Server"" Path=""\\server\db""/>
        </Bases>
      </Backup>"
    );
    
    // читаем и выводим все элементы Base из /Backup/Bases:
    foreach (XmlNode n in xml.SelectNodes("/Backup/Bases/Base"))
    {
      Console.WriteLine("Name: {0}", n.Attributes["Name"].Value);
      Console.WriteLine("MODE: {0}", n.Attributes["MODE"].Value);
      Console.WriteLine("Path: {0}", n.Attributes["Path"].Value);
    }

    3. Для больших файлов лучше использовать System.Xml.XmlReader (нагрузка на память минимальная). Для простоты работы, сделать комбинацию из выше указанных методов.

    Очень простой, но грубый пример использования XmlReader
    string source =
    (
      @"<?xml version=""1.0"" encoding=""utf-8"" ?>
      <Backup>
        <Basic>
          <Path1C>\\server\1cv8s.exe</Path1C>
        </Basic>
        <Bases>
          <Base Name=""b1"" MODE=""File"" Path=""\\server\Base\base""/>
          <Base Name=""bas2"" MODE=""Server"" Path=""\\server\db""/>
        </Bases>
      </Backup>"
    );
    
    using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(source)))
    // если из файла, то без MemoryStream; или лучше использовать FileStream
    // using (var xml = XmlReader.Create("XMLFile1.xml"))
    using (var xml = XmlReader.Create(ms))
    {
      while (xml.Read())
      {
        switch (xml.NodeType)
        {
          case XmlNodeType.Element:
            // нашли элемент Base
            if (xml.Name == "Base")
            {
              // выводим атрибуты
              Console.WriteLine("Name: {0}", xml.GetAttribute("Name"));
              Console.WriteLine("MODE: {0}", xml.GetAttribute("MODE"));
              Console.WriteLine("Path: {0}", xml.GetAttribute("Path"));
            }
            break;
        }
      }
    }
    Ответ написан
    Комментировать
  • Как сделать путь к файлу через textbox?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Видимо нужно указать имя файла в первом параметре:
    var file1 = new Attachment(textBox9.Text + "1.png");

    Вторым параметром может быть указан тип содержимого, в данном случае image/png:

    var file1 = new Attachment(textBox9.Text + "1.png", "image/png");


    PS: Для объединения путей лучше использовать функцию System.IO.Path.Combine(), это избавит от проблем со слешами:
    var file1 = new Attachment(Path.Combine(textBox9.Text, "1.png"), "image/png");
    Ответ написан
    Комментировать
  • Как enum'у назначить regex "любое число"(См.описание)?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    В перечислениях допустимы только целочисленные значения (byte, sbyte, short, ushort, int, uint, long и ulong), либо char.

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

    Вместо перечислений можно использовать константы (const) или readonly переменные. В последнем случае возможности по использованию различных типов данных не ограничены, в отличие от констант. Код для проверки все равно придется написать.
    Ответ написан
    Комментировать
  • Как можно преобразовать MatchCollection в массив строк в c#?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Либо циклом пройтись и собрать массив/коллекцию:
    var result = new List<string>();
    
    foreach (Match m in matches)
    {
      result.Add(m.Value);
    }
    
    // в result будет коллекция строк

    Либо можно использовать System.Linq:

    using System.Linq;
    var stringArray = matches.Cast<Match>().Select(m => m.Value).ToArray();

    Как-то показывал пример решателя, но на VB.NET. При желании, можно на C# сделать аналогично.
    Ответ написан
    3 комментария
  • Как сделать связь между объектами в propertygrid?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    В полной мере не понятна суть вопроса. Необходимо чтобы, например, изменяя значение свойства A первого класса, эти изменения отражались в свойстве X второго класса?

    Если так, то вероятно нужно смотреть в сторону события PropertyValueChanged:
    private void propertyGrid1_PropertyValueChanged(Object sender, PropertyValueChangedEventArgs e) 
    {
      System.Text.StringBuilder messageBoxCS = new System.Text.StringBuilder();
    
      messageBoxCS.AppendFormat("{0} = {1}", "ChangedItem", e.ChangedItem );
      messageBoxCS.AppendLine();
    
      messageBoxCS.AppendFormat("{0} = {1}", "OldValue", e.OldValue );
      messageBoxCS.AppendLine();
    
      MessageBox.Show(messageBoxCS.ToString(), "PropertyValueChanged Event" );
    }
    Ответ написан
    1 комментарий
  • Как выбрать из json ответа нужные значение?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    С помощью Newtonsoft.Json выполнить поиск по ключам можно так:

    var data = (JObject)JsonConvert.DeserializeObject("данные JSON");
          
    foreach(JObject item in data["response"]["items"])
    {
      // var photos = item.Properties().Where(p => p.Name.StartsWith("photo_")).ToArray();
      // если считать, что последнее изображение самое большое
      var photo = item.Properties().LastOrDefault(p => p.Name.StartsWith("photo_") && 
        p.Value != null && 
        p.Value.ToString() != ""
      );
    
      /*
      // вариант с извлечением номера и сортировкой
      // при условии, что после photo_ всегда будет число
      // (если нет, то придется это учитывать отдельно)
      var photo = item.Properties().Where(p => p.Name.StartsWith("photo_") && 
        p.Value != null && 
        p.Value.ToString() != ""
      ).OrderBy(p => Convert.ToInt32(p.Name.Substring(p.Name.LastIndexOf("_") + 1))).LastOrDefault();
      */
    
      if (photo != null)
      {
        // выводим адрес изображения в консоль
        Console.WriteLine(photo.Value.ToString());
      }
    }
    Ответ написан
    Комментировать
  • Как увеличить количество запросов к серверу за минимальное время?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Попробуйте использовать HttpClient:

    private async Task<string> Get(string url)
    {
      using (var client = new HttpClient())
      {
        using (var r = await client.GetAsync(new Uri(url)))
        {
          return await r.Content.ReadAsStringAsync();
        }
      }
    }

    Но придется вызов метода Get делать с await, и далее по цепочке вверх, добавлять async/await:

    string result = await Get("https://toster.ru/q/470456");

    В качестве альтернативного варианта, можно запускать запросы асинхронно и передавать результат выполнения запроса в функцию. С вашим кодом, примерно так:

    private void Get(string url)
    {
      Task.Run(async () =>
      {
        WebRequest req = WebRequest.Create(url);
        WebResponse resp = await req.GetResponseAsync();
        Stream stream = resp.GetResponseStream();
        StreamReader sr = new StreamReader(stream);
    
        string result = await sr.ReadToEndAsync();
    
        sr.Close();
    
        // передаем результат
        ResultCallback(url, result);
      });
    }
    
    private void ResultCallback(string url, string result)
    {
      // выводим в консоль результат
      Console.WriteLine(url);
      Console.WriteLine(result);
    }

    Аналогичный вариант с HttpClient
    private void Get(string url)
    {
      Task.Run(async () =>
      {
        using (var client = new HttpClient())
        {
          using (var r = await client.GetAsync(new Uri(url)))
          {
            string result = await r.Content.ReadAsStringAsync();
    
            ResultCallback(url, result);
          }
        }
      });
    }
    Обертка кода, указанного в тексте вопроса, с минимальными изменениями
    private void Get(string url)
    {
      // выполняем запрос в отдельном потоке
      Task.Run(() =>
      {
        WebRequest req = WebRequest.Create(url);
        WebResponse resp = req.GetResponse();
        Stream stream = resp.GetResponseStream();
        StreamReader sr = new StreamReader(stream);
    
        string result = sr.ReadToEnd();
    
        sr.Close();
    
        // передаем результат в функцию обратного вызова
        ResultCallback(url, result);
      });
    }
    
    private void ResultCallback(string url, string result)
    {
      Console.WriteLine(url);
      Console.WriteLine(result);
    }
    Вариант с оберткой Thread, если используются старая версия .NET
    private void Get(string url)
    {
      // создаем поток
      var t = new Thread(() =>
      {
        WebRequest req = WebRequest.Create(url);
        WebResponse resp = req.GetResponse();
        Stream stream = resp.GetResponseStream();
        StreamReader sr = new StreamReader(stream);
    
        string result = sr.ReadToEnd();
    
        sr.Close();
    
        ResultCallback(url, result);
      });
    
      // запускаем
      t.Start();
    }
    
    private void ResultCallback(string url, string result)
    {
      Console.WriteLine(url);
      Console.WriteLine(result);
    }
    Ответ написан
    Комментировать
  • Как в WebGrid asp.net mvc поменять количество выводимых страниц?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    @{ 
      var grid = new WebGrid(/*...*/);
    }
    
    @grid.GetHtml(mode: WebGridPagerModes.Numeric, numericLinksCount: 10)
    
    или отдельно список страниц:
    
    @grid.Pager(numericLinksCount: 10)

    https://msdn.microsoft.com/ru-ru/library/system.we...
    public IHtmlString GetHtml(
    	string tableStyle,
    	string headerStyle,
    	string footerStyle,
    	string rowStyle,
    	string alternatingRowStyle,
    	string selectedRowStyle,
    	string caption,
    	bool displayHeader,
    	bool fillEmptyRows,
    	string emptyRowCellValue,
    	IEnumerable<WebGridColumn> columns,
    	IEnumerable<string> exclusions,
    	WebGridPagerModes mode,
    	string firstText,
    	string previousText,
    	string nextText,
    	string lastText,
    	int numericLinksCount,
    	Object htmlAttributes
    )

    numericLinksCount
    Тип: System.Int32
    Число цифровых ссылок на ближайшие страницы WebGrid. Текст каждой цифровой ссылки на страницу содержит номер страницы. Задайте флаг Numeric параметра mode, чтобы эти элементы управления отображались на странице.

    https://msdn.microsoft.com/ru-ru/library/system.we...
    public HelperResult Pager(
    	WebGridPagerModes mode,
    	string firstText,
    	string previousText,
    	string nextText,
    	string lastText,
    	int numericLinksCount
    )

    numericLinksCount
    Тип: System.Int32
    Число отображаемых цифровых ссылок на страницы. По умолчанию используется значение 5.
    Ответ написан
  • Как объеденить массив int в 1 строку C#?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    // входящие данные
    var arr = new int[] { 5, 10, 7, 123, 0 };
    
    // Console.WriteLine(String.Join("+", arr.OrderBy(n => n).Select(n => n.ToString())));
    
    // сортируем
    var sorted = arr.OrderBy(n => n);
    
    // склеиваем
    Console.WriteLine(String.Join("+", sorted.Select(n => n.ToString())));
    
    // или без вызова ToString(), если используемая версия .NET позволит:
    // Console.WriteLine(String.Join("+", sorted));
    
    // или с вызовом ToArray() для ранних версий .NET:
    // String.Join("+", sorted.Select(n => n.ToString()).ToArray())
    Ответ написан
    4 комментария
  • Дружба C# и Linux, как?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Можно запускать обычные сборки через Mono или .NET Core. Последнее предпочтительней.

    Программа уровня «Hello world» будет просто запускаться через выше указанные решения, например:

    mono helloworld.exe
    dotnet helloworld.exe
    # выполнение из исходного кода в текущем каталоге:
    dotnet run

    Для более сложных решений может потребоваться дополнительная адаптация кода. Под .NET Core это сделать удобней и проще. Писать и собирать код вполне можно в Visual Studio под Windows.
    Ответ написан
    4 комментария
  • Как управлять состоянием полей обьекта через атрибуты?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Используйте BindingFlags:
    var managementsItems = this.GetType().GetMembers
    (
      BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public
    ).Where(m => Attribute.IsDefined(m, typeof(HideAttribute))).ToList();
    Ответ написан
    Комментировать
  • С чего начать обучение C# для разработки софта под соц.сети и дальнейшей работы с API этих соц.сетей?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Работа с API - это просто веб-запросы.

    Подготовка запросов и обработка ответов - это в большинстве своем сериализация/десериализация, в основном JSON-данных, реже XML.

    Все остальное будет зависеть от типа приложений, которые вы планируете разрабатывать.

    По работе с API социальных сетей лучше читать официальную документацию.

    У меня есть библиотека для авторизации по протоколу OAuth (используется многими, если не всеми, социальными сетями), которая помимо прочего, имеет унифицированные механизмы работы с API. Посмотреть на работу библиотеки можно по следующей ссылке: demo-oauth.nemiro.net

    Для многих крупных проектов (сайтов) можно найти готовые узкопрофильные решения.

    Ниже представлен небольшой пример использования библиотеки Nemiro.OAuth в проекте Windows Forms для авторизации через Instagram и использование полученного маркера доступа для загрузки списка последних изображений текущего пользователя. Изображения загружаются в ImageList и затем выводятся в ListView:
    using System;
    using System.Drawing;
    using System.Net.Http;
    using System.Windows.Forms;
    using Nemiro.OAuth;
    using Nemiro.OAuth.LoginForms;
    
    namespace InstagramWinForms
    {
    
      public partial class Form1 : Form
      {
    
        // базовый адрес API
        private const string API_BASE_URL = "https://api.instagram.com/v1";
    
        // элемент для хранения полученных изображений
        private ImageList ImageList = new ImageList();
    
        // элемент для вывода изображений
        private ListView ListView1 = new ListView();
    
        private string AccessToken;
    
        public Form1()
        {
          InitializeComponent();
    
          // размер изображений 150x150px, 16bit
          this.ImageList.ImageSize = new Size(150, 150);
          this.ImageList.ColorDepth = ColorDepth.Depth16Bit;
    
          // настраиваем список для вывода
          this.ListView1.View = View.LargeIcon;
          this.ListView1.LargeImageList = this.ImageList;
    
          this.ListView1.Dock = DockStyle.Fill;
    
          // добавляем список на форму
          this.Controls.Add(this.ListView1);
        }
    
        private void Form1_Load(object sender, EventArgs e)
        {
          // запрос на получение маркера доступа
          this.GetAccessToken();
        }
    
        private void GetAccessToken()
        {
          // создаем форму для Instagram
          // ВНИМАНИЕ: используйте собственный идентификатор и ключ
          // получить идентификатор и ключ можно на сайте instagram:
          // https://www.instagram.com/developer/clients/manage/
          var login = new InstagramLogin
          (
            // client id вашего приложения
            "9fcad1f7740b4b66ba9a0357eb9b7dda", 
            // client key вашего приложения
            "3f04cbf48f194739a10d4911c93dcece", 
            // требуется адрес возврата, 
            // можно использовать указанный, 
            // но лучше сделать свой
            "http://oauthproxy.nemiro.net/",
            // права доступа
            // https://www.instagram.com/developer/authorization/
            // для public_content (и возможно других) убедитесь, 
            // что в настройках приложения (на сайте instagram) 
            // в разделе Permissions нет никаких требований 
            // (если требования есть, то чтобы все работало, 
            // нужно их удовлетворить :-) ...)
            scope: "basic public_content",
            // требуем получить данные профиля пользователя
            loadUserInfo: true
          );
    
          // привязываем форму авторизации к текущей форме
          login.Owner = this;
    
          // показываем форму
          login.ShowDialog();
    
          if (login.IsSuccessfully)
          {
            // все прошло успешно, запоминаем маркер доступа
            this.AccessToken = login.AccessToken.Value;
    
            // выводим в заголовок текущей формы имя пользователя
            this.Text = (login.UserInfo.DisplayName ?? login.UserInfo.UserName);
    
            // получаем изображения
            this.GetRecentMedia();
          }
          else
          {
            MessageBox.Show("Error...", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
          }
        }
    
        private void GetRecentMedia()
        {
          // отправляем запрос на получение изображений
          OAuthUtility.GetAsync
          (
            String.Format
            (
              "{0}/users/self/media/recent?access_token={1}", 
              API_BASE_URL, 
              this.AccessToken
            ),
            // результат запроса будет передан в метод GetRecentMedia_Result
            callback: GetRecentMedia_Result
          );
        }
    
        private async void GetRecentMedia_Result(RequestResult result)
        {
          if (result.StatusCode == 200)
          {
            // получили успешный ответ
            // обрабатываем его
            foreach (UniValue item in result["data"])
            {
              // загружаем текущую картинку
              using (var client = new HttpClient())
              {
                var s = await client.GetStreamAsync(item["images"]["thumbnail"]["url"].ToString());
    
                // добавляем изображение в список
                Invoke(new Action(() => this.ImageList.Images.Add(Image.FromStream(s))));
              }
    
              // создаем элемент для вывода в список 
              var image = new ListViewItem();
              // название изображения
              image.Text = item["caption"]["text"].ToString();
              // индекс изображения в списке (ImageList)
              image.ImageIndex = this.ImageList.Images.Count - 1;
    
              // добавляем элемент в список
              Invoke(new Action(() => this.ListView1.Items.Add(image)));
            }
          }
          else
          {
            this.ShowError(result);
          }
        }
    
        private void ShowError(RequestResult result)
        {
          if (result["meta"]["error_message"].HasValue)
          {
            MessageBox.Show
            (
              result["meta"]["error_message"].ToString(), 
              "Error", 
              MessageBoxButtons.OK, 
              MessageBoxIcon.Error
            );
          }
          else
          {
            MessageBox.Show
            (
              result.ToString(), 
              "Error", 
              MessageBoxButtons.OK, 
              MessageBoxIcon.Error
            );
          }
        }
    
        private void button1_Click(object sender, EventArgs e)
        {
          this.GetRecentMedia();
        }
    
      }
    
    }

    preview.gif?raw=true
    Код проекта можно найти по следующей ссылке:
    https://github.com/alekseynemiro/nemiro.oauth.dll/...
    Ответ написан
    2 комментария
  • Какой шаблон для RegEx коррентный?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    // .* - может съесть лишнего, 
    // если есть возможность, лучше строго ограничивать
    // в данном случае четкой границей 
    // может служить открытие следующего тега (<)
    // "(.+?)<div" имеет смысл использовать, если в искомом тексте могут быть другие теги
    // class="margin-top-xx-small" тоже можно использовать, 
    // но только если это действительно необходимо
    var pattern = @"<div(\s+)class=""currency-table__rate__text"">(?<data>[^\<]+)<";
    var reg = new Regex(pattern, RegexOptions.IgnoreCase);
    var m = reg.Match(value); // вместо value переменная с данными для разбора
    var result = m.Groups["data"].Value.Trim();
    Console.WriteLine(result);
    Ответ написан
    Комментировать
  • Возможно ли вообще организовать локальную MySQL для C#, доступную для коннектора из программы?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Конечно возможно. Интернет для локальных соединений не нужен.

    Строка соединения примерно такая:

    Server=localhost;Database=example;UID=username;Password=password

    где:
    • example - имя базы данных;
    • usersname - имя пользователя;
    • password - пароль.

    Если используется нестандартный порт, то его можно указать отдельно: Port=123.

    Denwer и прочие тут вообще не нужны. Достаточно скачать официальный дистрибутив MySql и установить.

    С помощью MySQL Workbench можно управлять базами данных через графический интерфейс.

    Код получения данных из MySql в C# может быть примерно таким:

    var connectionString = "Server=localhost;Database=example;UID=username;Password=password";
    using (var connection = new MySqlConnection(connectionString))
    {
      // открываем соединение
      connection.Open();
    
      // создаем команду
      var cmd = new MySqlCommand();
      cmd.Connection = connection;
      cmd.CommandText = "SELECT * FROM table1";
      
      // создаем адаптер
      var adapter = new MySqlDataAdapter(cmd);
      // создаем таблицу
      var table = new DataTable();
      // получаем данные в таблицу
      adapter.Fill(table);
      
      // выводим
      foreach (DataRow row in table.Rows)
      {
        Console.WriteLine(row[0]);
      }
    }
    Ответ написан
    Комментировать
  • Как сделать возможным запуск c# приложения на разных платформах NET?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Совместимость версий в .NET Framework
    Элемент <supportedRuntime>
    <configuration>
      <startup>
        <supportedRuntime version="v4.0" /> 
        <supportedRuntime version="v2.0.50727" /> 
      </startup>
    </configuration>

    также хотелось бы узнать как компилировать в месте с ним.

    Код для младших версий должен нормально работать в старших.

    В крайнем случае можно использовать Директивы препроцессора C#.
    Ответ написан
  • Почему Margin у button не меняется?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Вероятно что-то, например ThicknessAnimation, меняет Margin у кнопки.

    Нужно убрать анимацию перед внесением изменений:
    Button btn = (Button)sender;
    
    button.BeginAnimation(MarginProperty, null);
    
    btn.Margin = new Thickness();
    Thickness margin = btn.Margin;
    // ...
    Ответ написан
    Комментировать