<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Николай</title><author><name>Николай</name></author><id>https://teletype.in/atom/nigushch</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/nigushch?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@nigushch?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=nigushch"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/nigushch?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-04-30T08:52:07.712Z</updated><entry><id>nigushch:H1Oykl8M4</id><link rel="alternate" type="text/html" href="https://teletype.in/@nigushch/H1Oykl8M4?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=nigushch"></link><title>Вопросы на собеседованиях по C# и .Net. На позицию junior/middle. Часть 1.</title><published>2019-01-11T15:34:35.466Z</published><updated>2019-11-24T15:08:47.578Z</updated><category term="topic1640" label="Прочее"></category><summary type="html">Совсем скоро настанет момент, когда нужно будет устраиваться на другую работу, а, соответственно, начнутся и собеседования. Для того чтобы не облажаться получить должность, желательно подготовиться. Поэтому появилась идея создать серию статей, в которых будут собраны различные вопросы, которые могут Вам попасться, и дать на них ответы. Материалы брались из различных источников, список будет в конце. Предлагайте в комментариях свои варианты вопросов, они так же будут добавлены в общий список. Итак, начнем!</summary><content type="html">
  &lt;p&gt;Совсем скоро настанет момент, когда нужно будет устраиваться на другую работу, а, соответственно, начнутся и собеседования. Для того чтобы &lt;s&gt;не облажаться&lt;/s&gt; получить должность, желательно подготовиться. Поэтому появилась идея создать серию статей, в которых будут собраны различные вопросы, которые могут Вам попасться, и дать на них ответы. Материалы брались из различных источников, список будет в конце. Предлагайте в комментариях свои варианты вопросов, они так же будут добавлены в общий список. Итак, начнем!&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2&gt;!!НАШ БЛОГ ПЕРЕЕХАЛ!!&lt;/h2&gt;
  &lt;p&gt;Мы создали свой сайт! Все материалы, опубликованные в этом блоге, переехали туда. &lt;/p&gt;
  &lt;h3&gt;Наш новый сайт &lt;a href=&quot;https://maddevelop.ru/&quot; target=&quot;_blank&quot;&gt;maddevelop.ru&lt;/a&gt;&lt;/h3&gt;
  &lt;p&gt;А данную статью вы можете найти по ссылке ниже:&lt;/p&gt;
  &lt;p&gt;&lt;a href=&quot;https://maddevelop.ru/Textbook/ViewSelectedArticle?textbookName=C%23&amp;sectionName=%D0%A1%D0%BE%D0%B1%D0%B5%D1%81%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%20%D0%BF%D0%BE%20C%23%20%D0%B8%20.NET&amp;subsectionName=%D0%A1%D0%BE%D0%B1%D0%B5%D1%81%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%20%D0%BD%D0%B0%20%D0%BF%D0%BE%D0%B7%D0%B8%D1%86%D0%B8%D1%8E%20junior%2Fmiddle&amp;articleName=%231%20%D0%91%D0%BB%D0%BE%D0%BA%20%D0%B2%D0%BE%D0%BF%D1%80%D0%BE%D1%81%D0%BE%D0%B2%20(%D0%B2%D0%BE%D0%BF%D1%80%D0%BE%D1%81%D1%8B%201-5)&quot; target=&quot;_blank&quot;&gt;https://maddevelop.ru/Textbook/ViewSelectedArticle?textbookName=C%23&amp;amp;sectionName=%D0%A1%D0%BE%D0%B1%D0%B5%D1%81%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%20%D0%BF%D0%BE%20C%23%20%D0%B8%20.NET&amp;amp;subsectionName=%D0%A1%D0%BE%D0%B1%D0%B5%D1%81%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%20%D0%BD%D0%B0%20%D0%BF%D0%BE%D0%B7%D0%B8%D1%86%D0%B8%D1%8E%20junior%2Fmiddle&amp;amp;articleName=%231%20%D0%91%D0%BB%D0%BE%D0%BA%20%D0%B2%D0%BE%D0%BF%D1%80%D0%BE%D1%81%D0%BE%D0%B2%20(%D0%B2%D0%BE%D0%BF%D1%80%D0%BE%D1%81%D1%8B%201-5)&lt;/a&gt;&lt;/p&gt;
  &lt;p&gt;P.S. движок teletype.in очень странно интерпретирует ссылку, и пришлось вставлять ее полным текстом&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2&gt;Вопрос 1.&lt;/h2&gt;
  &lt;p&gt;Есть следующее объявление классов A и B:&lt;/p&gt;
  &lt;pre&gt;class A
{
	virtual void Foo()
	{
		Console.Write(&amp;quot;Class A&amp;quot;);
	}
}
class B: A
{
	override void Foo()
	{
		Console.Write(&amp;quot;Class B&amp;quot;);
	}
}
&lt;/pre&gt;
  &lt;p&gt;Что выведут на консоль такие вызовы метода Foo():&lt;/p&gt;
  &lt;pre&gt;B obj1 = new A();
obj.Foo();

B obj2 = new B();
obj2.Foo();

A obj3 = new B();
obj3.Foo();
&lt;/pre&gt;
  &lt;p&gt;&lt;strong&gt;Ответ:&lt;/strong&gt;&lt;/p&gt;
  &lt;p&gt;Во-первых ошибка в том, что не указаны модификаторы доступа в определениях метода Foo в классах A и B.&lt;/p&gt;
  &lt;blockquote&gt;Нельзя использовать модификатор &lt;code&gt;virtual&lt;/code&gt; с Модификаторами &lt;code&gt;static&lt;/code&gt;, &lt;code&gt;abstract&lt;/code&gt;, &lt;code&gt;private&lt;/code&gt;, или &lt;code&gt;override&lt;/code&gt;. (ссылка на источник: https://docs.microsoft.com/ru-ru/dotnet/csharp/language-reference/keywords/virtual )&lt;/blockquote&gt;
  &lt;p&gt;А по умолчанию при определении метода ему присваивается модификатор private.&lt;/p&gt;
  &lt;p&gt;Во-вторых когда создается переменная obj1 типа B и в нее помещается объект типа A&lt;/p&gt;
  &lt;pre&gt;B obj1 = new A();
&lt;/pre&gt;
  &lt;p&gt;производится неявный downcast, что недопустимо.&lt;/p&gt;
  &lt;p&gt;Правильный код бы выглядел вот так&lt;/p&gt;
  &lt;pre&gt;class A
{
	public virtual void Foo()
	{
		Console.Write(&amp;quot;Class A&amp;quot;);
	}
}
class B: A
{
	public override void Foo()
	{
		Console.Write(&amp;quot;Class B&amp;quot;);
	}
}
class Program
{
  static void Main()
  {   
    B obj2 = new B();
    obj2.Foo();
    
    A obj3 = new B();
    obj3.Foo();
  } 
}
&lt;/pre&gt;
  &lt;p&gt;Тогда результатом будет:&lt;/p&gt;
  &lt;pre&gt;B
B
&lt;/pre&gt;
  &lt;h2&gt;Вопрос 2.&lt;/h2&gt;
  &lt;p&gt;Есть следующая структура:&lt;/p&gt;
  &lt;pre&gt;public struct S : IDisposable
{
    private bool dispose;
    public void Dispose()
    {
        dispose = true;
    }
    public bool GetDispose()
    {
        return dispose;
    }
}
&lt;/pre&gt;
  &lt;p&gt;Что будет выведено в следующем случае:&lt;/p&gt;
  &lt;pre&gt;var s = new S();
using (s)
{
    Console.WriteLine(s.GetDispose());
}
Console.WriteLine(s.GetDispose());
&lt;/pre&gt;
  &lt;p&gt;Варианты ответов:&lt;/p&gt;
  &lt;ol&gt;
    &lt;li&gt;true, true&lt;/li&gt;
    &lt;li&gt;true, false&lt;/li&gt;
    &lt;li&gt;false, true&lt;/li&gt;
    &lt;li&gt;false, false&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p&gt;&lt;strong&gt;Ответ:&lt;/strong&gt;&lt;/p&gt;
  &lt;p&gt;Правильный ответ под номером 4 (false, false). Это происходит потому, что блок&lt;/p&gt;
  &lt;pre&gt;using (s)
{
	...
}
&lt;/pre&gt;
  &lt;p&gt;на самом деле выполняется как&lt;/p&gt;
  &lt;pre&gt;using (S s2 = s)
{
	...
}
&lt;/pre&gt;
  &lt;p&gt;а так как структура это &lt;em&gt;тип значения&lt;/em&gt;, а не &lt;em&gt;ссылочный тип&lt;/em&gt;, она копируется по значению, а не по ссылке. Поэтому все действия будут происходить над копией, а не над исходным экземпляром.&lt;/p&gt;
  &lt;p&gt;На эту тему есть &lt;a href=&quot;https://ericlippert.com/2011/03/14/to-box-or-not-to-box/&quot; target=&quot;_blank&quot;&gt;статья&lt;/a&gt;. (скорее всего сделаю перевод этой статьи и опубликую здесь, уж очень она познавательна)&lt;/p&gt;
  &lt;h2&gt;Вопрос 3.&lt;/h2&gt;
  &lt;p&gt;Есть следующий код:&lt;/p&gt;
  &lt;pre&gt;List&amp;lt;Action&amp;gt; actions = new List&amp;lt;Action&amp;gt;();
for(var count=0; count&amp;lt;10; count++)
{
    actions.Add(() =&amp;gt; Console.WriteLine(count));
}
foreach(var action in actions)
{
    action();
}
&lt;/pre&gt;
  &lt;p&gt;Что будет выведено на консоль? Варианты ответов:&lt;/p&gt;
  &lt;ol&gt;
    &lt;li&gt;0, 1, 2, 3, 4, 5, 6, 7, 8, 9&lt;/li&gt;
    &lt;li&gt;10, 10, 10, 10, 10, 10, 10, 10, 10, 10&lt;/li&gt;
    &lt;li&gt;Код сгенерирует исключение&lt;/li&gt;
    &lt;li&gt;0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p&gt;&lt;strong&gt;Ответ:&lt;/strong&gt;&lt;/p&gt;
  &lt;p&gt;Правильный ответ 2 (выведет 10 раз число 10).&lt;/p&gt;
  &lt;p&gt;Это происходит потому, что в &lt;em&gt;цикле for&lt;/em&gt; в переменную &lt;em&gt;actions&lt;/em&gt; будет записано 10 действий WriteLine(count). После 10 итерации &lt;em&gt;цикла for&lt;/em&gt; переменная &lt;em&gt;count&lt;/em&gt; примет значение 10. А когда мы будем пробегаться по &lt;em&gt;циклу foreach,&lt;/em&gt; мы будем вызывать подряд 10 методов &lt;em&gt;Console.WriteLine(count)&lt;/em&gt; из списка &lt;em&gt;actions&lt;/em&gt;, где&lt;em&gt; count = 10&lt;/em&gt;.&lt;/p&gt;
  &lt;h2&gt;Вопрос 4.&lt;/h2&gt;
  &lt;p&gt;Что будет выведено на консоль в результате следующих операций:&lt;/p&gt;
  &lt;pre&gt;int i = 1;
object obj = i;
++i;
Console.WriteLine(i);
Console.WriteLine(obj);
Console.WriteLine((short)obj);
&lt;/pre&gt;
  &lt;p&gt;&lt;strong&gt;Ответ:&lt;/strong&gt;&lt;/p&gt;
  &lt;p&gt;Произойдет ошибка на этапе выполнения в последней строке. При упаковке в переменной типа &lt;em&gt;int &lt;/em&gt;в переменную типа&lt;em&gt; object&lt;/em&gt; распаковка может происходить только в этот же тип, а уже после этого можно производить другие приведения. (&lt;a href=&quot;https://blogs.msdn.microsoft.com/ericlippert/2009/03/19/representation-and-identity/&quot; target=&quot;_blank&quot;&gt;ссылка на пояснение на msdn&lt;/a&gt;)&lt;/p&gt;
  &lt;h2&gt;Вопрос 5.&lt;/h2&gt;
  &lt;p&gt;Что выведет на консоль следующий код:&lt;/p&gt;
  &lt;pre&gt;var s1 = string.Format(&amp;quot;{0}{1}&amp;quot;, &amp;quot;abc&amp;quot;, &amp;quot;cba&amp;quot;);
var s2 = &amp;quot;abc&amp;quot; + &amp;quot;cba&amp;quot;;
var s3 = &amp;quot;abccba&amp;quot;;
 
Console.WriteLine(s1 == s2);
Console.WriteLine((object)s1==(object)s2);
Console.WriteLine(s2==s3);
Console.WriteLine((object)s2==(object)s3);
&lt;/pre&gt;
  &lt;p&gt;Варианты ответов:&lt;/p&gt;
  &lt;ol&gt;
    &lt;li&gt;true, false, true, true&lt;/li&gt;
    &lt;li&gt;true, true, true, true&lt;/li&gt;
    &lt;li&gt;true, false, true, false&lt;/li&gt;
    &lt;li&gt;true, false, false, false&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p&gt;&lt;strong&gt;Ответ:&lt;/strong&gt;&lt;/p&gt;
  &lt;p&gt;Ухххх...а с этим вопросом можно сломать мозг, здесь затрагивается тема интернирования строк. Ответом будет номер 1 (true false true true). Это происходит потому, что в C# есть пул интернирования в котором хранятся ссылки на строки, подробнее эта тема будет рассмотрена отдельно. &lt;/p&gt;
  &lt;p&gt;А вкратце можно ответить так. При запуске программы среда CLR находит все строковые литералы и добавляет их в пул интернирования до ее выполнения. При создании новых переменных с этими значениями в них помещается только ссылка из пула. Операция конкатенации воспринемается средой CLR в качестве целого строкового литерала (это будет наглядно если посмотреть код в программе ildasm), а вот операция String.Format создаёт строку уже в момент выполнения программы и переменная получит другую ссылку, хотя по значению они будут равны. Поэтому при сравнении ссылок на s1 и s2 программа нам выдает false, а в этот же момент s2 и s3 true.&lt;/p&gt;
  &lt;h2&gt;Итог:&lt;/h2&gt;
  &lt;p&gt;В этой статье были рассмотрены только пять вопросов, но дальше-больше, ждите обновлений, а также пишите в комментариях варианты своих вопросов и.&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;Источники:&lt;/strong&gt;&lt;/p&gt;
  &lt;p&gt;&lt;a href=&quot;https://metanit.com/sharp/interview/1.1.php&quot; target=&quot;_blank&quot;&gt;Metanit. Собеседование по C#. Часть 1&lt;/a&gt;&lt;/p&gt;
  &lt;p&gt;&lt;a href=&quot;https://metanit.com/sharp/interview/1.2.php&quot; target=&quot;_blank&quot;&gt;Metanit. Собеседование по C#. Часть 2&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>nigushch:ryWUPUIlN</id><link rel="alternate" type="text/html" href="https://teletype.in/@nigushch/ryWUPUIlN?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=nigushch"></link><title>Программа для добавления/удаления строки к именам файлов в папке. Часть 2.</title><published>2018-12-18T19:34:02.540Z</published><updated>2018-12-19T18:11:22.055Z</updated><category term="topic309" label="Проекты"></category><category term="wpf" label="WPF"></category><summary type="html">Теперь рассмотрим процесс реализации класса ViewModel, наследуемого от ViewModelBase. Это абстрактный класс, который содержится в библиотеке MVVM Light. С помощью него реализуется обновление данных в свойствах, привязанных к элементам UI, а так же возможность передачи сообщений между объектами.</summary><content type="html">
  &lt;p&gt;Теперь рассмотрим процесс реализации класса ViewModel, наследуемого от ViewModelBase. Это абстрактный класс, который содержится в библиотеке MVVM Light. С помощью него реализуется обновление данных в свойствах, привязанных к элементам UI, а так же возможность передачи сообщений между объектами.&lt;/p&gt;
  &lt;p&gt;Начнем с описания логики работы первой вкладки программы «Добавление к имени файла»&lt;/p&gt;
  &lt;h2&gt;Реализация добавления строки к имени файла.&lt;/h2&gt;
  &lt;p&gt;Во-первых нам нужно связать TextBox’ы с соответствующими свойствами в MainViewModel через алгоритм привязки.&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;xaml&lt;/strong&gt;&lt;/p&gt;
  &lt;pre&gt;&amp;lt;!--Путь до папки с файлами--&amp;gt;
&amp;lt;TextBox Grid.Column=&amp;quot;0&amp;quot; Name=&amp;quot;PathToFolderAddString_tb&amp;quot; 
   Text=&amp;quot;{Binding PathToFilesForAddString_Renamer, Mode=TwoWay,
   UpdateSourceTrigger=PropertyChanged}&amp;quot;/&amp;gt;
&amp;lt;!--Строка до имени файла--&amp;gt;
&amp;lt;TextBox Name=&amp;quot;AddTextBefore_tb&amp;quot; 
   Text=&amp;quot;{Binding StringBeforeFileName_Renamer, 
   UpdateSourceTrigger=PropertyChanged}&amp;quot;/&amp;gt;
&amp;lt;!--Строка после имени файла--&amp;gt;
&amp;lt;TextBox Name=&amp;quot;AddTextAfter_tb&amp;quot; 
   Text=&amp;quot;{Binding StringAfterFileName_Renamer, 
   UpdateSourceTrigger=PropertyChanged}&amp;quot;/&amp;gt;
&amp;lt;!--Строка в имени файла--&amp;gt;
&amp;lt;TextBox Name=&amp;quot;InsertTextOnPosition_td&amp;quot; 
   Text=&amp;quot;{Binding InsertTextOnPosition_Renamer, 
   UpdateSourceTrigger=PropertyChanged}&amp;quot;/&amp;gt;
&lt;/pre&gt;
  &lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
  &lt;pre&gt;//Путь до папки в которой переименовываются файл
private string _pathToFilesForAddString_Renamer;
public string PathToFilesForAddString_Renamer
  {
    get { return _pathToFilesForAddString_Renamer; }
    set
      {
        _pathToFilesForAddString_Renamer = value;
        //Если меняется путь, то автоматическое 
        //слежение за папкой выключается
        if (AutoWatchingForFolder)
        {
          AutoWatchingForFolder = false;
        }
        RaisePropertyChanged(nameof(PathToFilesForAddString_Renamer));
      }
   }
//Строка которую нужно вставить до имени файла
private string _stringBeforeFileName_Renamer = &amp;quot;&amp;quot;;
public string StringBeforeFileName_Renamer
  {
   get { return _stringBeforeFileName_Renamer; }
   set
    {
      _stringBeforeFileName_Renamer = value;
      RaisePropertyChanged(nameof(StringBeforeFileName_Renamer));
    }
  }
//Строка которую нужно вставить после имени файла
private string _stringAfterFileName_Renamer = &amp;quot;&amp;quot;;
public string StringAfterFileName_Renamer
  {
    get { return _stringAfterFileName_Renamer; }
    set
    {
      _stringAfterFileName_Renamer = value;
      RaisePropertyChanged(nameof(StringAfterFileName_Renamer));
    }
  }
//Строка которую нужно вставить на определенную позицию
private string _insertTextOnPosition_Renamer = &amp;quot;&amp;quot;;
public string InsertTextOnPosition_Renamer
  {
    get { return _insertTextOnPosition_Renamer; }
    set
    {
      _insertTextOnPosition_Renamer = value;
      RaisePropertyChanged(nameof(InsertTextOnPosition_Renamer));
    }
  }
&lt;/pre&gt;
  &lt;p&gt;Так как в WPF нет элемента NumericUpDown, пришлось его искать в сторонних библиотеках. Выбор пал на &lt;a href=&quot;https://github.com/xceedsoftware/wpftoolkit&quot; target=&quot;_blank&quot;&gt;Xceed&lt;/a&gt;, она есть как платная, так и бесплатная. Подключить ее можно через менеджер пакетов NuGet. Чтобы использовать ее элементы, нам нужно прописать:&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;xaml&lt;/strong&gt;&lt;/p&gt;
  &lt;pre&gt;xmlns:xctk=”http://schemas.xceed.com/wpf/xaml/toolkit”
&lt;/pre&gt;
  &lt;p&gt;После этого можно создать сам элемент и привязать его к свойству&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;xaml&lt;/strong&gt;&lt;/p&gt;
  &lt;pre&gt;&amp;lt;xctk:IntegerUpDown Minimum=&amp;quot;0&amp;quot; Margin=&amp;quot;10 5 0 5&amp;quot; 
  Text=&amp;quot;{Binding InputPosition_Renamer, 
  UpdateSourceTrigger=PropertyChanged}&amp;quot;/&amp;gt;
&lt;/pre&gt;
  &lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
  &lt;pre&gt;//Позиция начиная с которой нужно вставить строку
private int _inputPosition_Renamer = 0;
public int InputPosition_Renamer
    {
      get { return _inputPosition_Renamer; }
      set
      {
        _inputPosition_Renamer = value;
        RaisePropertyChanged(nameof(InputPosition_Renamer));
      }
    }
&lt;/pre&gt;
  &lt;p&gt;Помимо технологии привязки данных, в WPF предусмотрено связывание действий элементов Button с методами класса ViewModel через систему команд. Для этого существует вспомогательный класс RelayCommand, наследуемый от интерфейса ICommand. Его реализация уже встроена в библиотеку MVVM Light, но его можно реализовать и самостоятельно. &lt;em&gt;(Если нужна будет реализация напишу в комментариях)&lt;/em&gt;.&lt;/p&gt;
  &lt;p&gt;Для того чтобы связать команду и визуальный элемент напишем следующее:&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;xaml&lt;/strong&gt;&lt;/p&gt;
  &lt;pre&gt;&amp;lt;Button Name=&amp;quot;RenameFilesOneTime_btn&amp;quot; 
  Command=&amp;quot;{Binding RenameFiles_Renaimer_Command}&amp;quot; 
  Content=&amp;quot;Переименовать файлы&amp;quot; /&amp;gt;
&lt;/pre&gt;
  &lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
  &lt;pre&gt;//Команда для переименовывания файлов
private RelayCommand _renameFiles_Renamer_Command;
public RelayCommand RenameFiles_Renaimer_Command
    {
      get
      {
        return _renameFiles_Renamer_Command ?? 
          (_renameFiles_Renamer_Command = new RelayCommand(() =&amp;gt;
        {
          RenameFilesMethod_Renamer(PathToFilesForAddString_Renamer);
        }));
      }
    }
&lt;/pre&gt;
  &lt;p&gt;Метод &lt;strong&gt;RenameFilesMethod_Renamer(string pathToFolder)&lt;/strong&gt; принимает на вход путь до папки, в которой лежат файлы.&lt;/p&gt;
  &lt;pre&gt;//Метод для переименовывания файлов в папке
private void RenameFilesMethod_Renamer(string pathToFolder)
 {
   if (CheckEnteredPath(pathToFolder) == 0)
   {
     return;
   }

   //Процесс переименования
   IEnumerable&amp;lt;FileInfo&amp;gt; filesToRename = Directory.GetFiles(pathToFolder)
                                            .Select(f =&amp;gt; new FileInfo(f));
   foreach (FileInfo fileInfo in filesToRename)
   {
     string newFileName = RenameFileMethod_Renamer(fileInfo);
     if (newFileName == &amp;quot;errorExceptionCheckIt&amp;quot;)
     {
       return;
     }
     Messenger.Default.Send(new AddInfoInLogFileMessage()
     {
       MessageForLogFile = &amp;quot;Файл &amp;quot; + fileInfo.Name + &amp;quot; переименован в &amp;quot; + newFileName,
       TextColorInLog = &amp;quot;#000000&amp;quot;
     });
   }
 }
&lt;/pre&gt;
  &lt;p&gt;Метод &lt;strong&gt;RenameFileMethod_Renamer(FileInfo inputFile)&lt;/strong&gt; сделан для удобства, потому что позже будет реализован алгоритм постоянного сканирования папки на наличие новых файлов и этот метод пригодится.&lt;/p&gt;
  &lt;pre&gt;//Метод для переименовывания одного файла
private string RenameFileMethod_Renamer(FileInfo inputFile)
 {
   try
   {
    string newFileName;
    newFileName = $@&amp;quot;{StringBeforeFileName_Renamer}{
               Path.GetFileNameWithoutExtension(inputFile.Name).Insert(InputPosition_Renamer,
               InsertTextOnPosition_Renamer)
             }&amp;quot; +
            $@&amp;quot;{StringAfterFileName_Renamer}{inputFile.Extension}&amp;quot;;
    string newFileFullPath = Path.Combine(inputFile.DirectoryName, newFileName);
    File.Move(inputFile.FullName, newFileFullPath);
     return newFileName;
   }
   catch (Exception e)
   {
     DispatcherHelper.CheckBeginInvokeOnUI(() =&amp;gt;
     {
       Messenger.Default.Send(new AddInfoInLogFileMessage()
       {
         MessageForLogFile = e.Message,
         TextColorInLog = &amp;quot;#000000&amp;quot;
       });
     });
   }
   return &amp;quot;errorExceptionCheckIt&amp;quot;;
 }
&lt;/pre&gt;
  &lt;p&gt;Метод &lt;strong&gt;CheckEnteredPath(string pathToFolder)&lt;/strong&gt; проверяет, правильный ли путь был передан на вход метода, выполняющего переименование.&lt;/p&gt;
  &lt;pre&gt;private int CheckEnteredPath(string pathToFolder)
 {
   //Проверка наличия указанного пут����
   if (pathToFolder == &amp;quot;&amp;quot;)
   {
     Messenger.Default.Send(new AddInfoInLogFileMessage() { MessageForLogFile = &amp;quot;Не задан путь до папки!&amp;quot;, TextColorInLog = &amp;quot;#B22222&amp;quot; });
     return 0;
   }
   //Проверка существования выбранной папаки
   if (!System.IO.Directory.Exists(pathToFolder))
   {
     Messenger.Default.Send(new AddInfoInLogFileMessage() { MessageForLogFile = &amp;quot;Такой папки не существует!&amp;quot;, TextColorInLog = &amp;quot;#B22222&amp;quot; });
     return 0;
   }
   return 1; 
 }
&lt;/pre&gt;
  &lt;p&gt;Чтобы получить список файлов находящихся в выбранной папке, мы используем метод&lt;/p&gt;
  &lt;pre&gt;Directory.GetFiles(pathToFolder)
&lt;/pre&gt;
  &lt;p&gt;Который на выход получает путь до папки а возвращает имена файлов в ней.&lt;/p&gt;
  &lt;p&gt;Далее эти имена мы заносим в строго типизированный перечислитель:&lt;/p&gt;
  &lt;pre&gt;IEnumerable&amp;lt;FileInfo&amp;gt; filesToRename = Directory.GetFiles(pathToFolder).Select(f =&amp;gt; new FileInfo(f));
&lt;/pre&gt;
  &lt;p&gt;Тип FileInfo предоставляет свойства и методы для работы с файлами.&lt;/p&gt;
  &lt;p&gt;Если переименование проходит успешно, то мы отправляем сообщение из класса ViewModel в MainWindow.xaml.cs&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;Код во ViewModel&lt;/strong&gt;&lt;/p&gt;
  &lt;pre&gt;Messenger.Default.Send(new AddInfoInLogFileMessage()
  {
    MessageForLogFile = &amp;quot;Файл &amp;quot; + fileInfo.Name + &amp;quot; переименован в &amp;quot; + newFileName,
    TextColorInLog = &amp;quot;#000000&amp;quot;
 });
&lt;/pre&gt;
  &lt;p&gt;&lt;strong&gt;В конструкторе класса MainWindow.xaml.cs&lt;/strong&gt;&lt;/p&gt;
  &lt;pre&gt;Messenger.Default.Register&amp;lt;AddInfoInLogFileMessage&amp;gt;(this, x =&amp;gt;
{
  LogText_tb.AppendText(DateTime.Now.ToShortDateString() + &amp;quot; &amp;quot; + DateTime.Now.ToLongTimeString() + 
   &amp;quot; &amp;quot; + x.MessageForLogFile + &amp;quot;\n&amp;quot;);
  LogText_tb.ScrollToEnd();
  ScrollViewerForLog.ScrollToBottom();
});
&lt;/pre&gt;
  &lt;p&gt;Чтобы отправлять сообщения мы создали вспомогательный класс &lt;strong&gt;AddInfoInLogFileMessage&lt;/strong&gt; в папке Helpers. Он содержит в себе свойства, которые мы можем соотнести с параметрами, передаваемыми через сообщения.&lt;/p&gt;
  &lt;pre&gt;class AddInfoInLogFileMessage
 {
   public string MessageForLogFile { get; set; }
   public string TextColorInLog { get; set; }
 }
&lt;/pre&gt;
  &lt;p&gt;Таким образом был описан алгоритм для добавления строки к именам всех файлов в выбранной папке. Теперь же покажу, как реализовать автоматическое отслеживание появления изменение структуры папки.&lt;/p&gt;
  &lt;h2&gt;Автоматическое переименование файлов в папке.&lt;/h2&gt;
  &lt;p&gt;UI содержит элемент CheckBox, который включает поток для отслеживания изменений в структуре папки (добавление, удаление, переименование файлов в ней)&lt;/p&gt;
  &lt;pre&gt;&amp;lt;CheckBox Margin=&amp;quot;0 10 0 10&amp;quot; IsChecked=&amp;quot;{Binding AutoWatchingForFolder,
          UpdateSourceTrigger=PropertyChanged}&amp;quot;&amp;gt;
  &amp;lt;TextBlock Text=&amp;quot;Автоматически переименовывать файлы при появлении в папке&amp;quot; TextWrapping=&amp;quot;Wrap&amp;quot;/&amp;gt;
    &amp;lt;i:Interaction.Triggers&amp;gt;
      &amp;lt;i:EventTrigger EventName=&amp;quot;Checked&amp;quot;&amp;gt;
         &amp;lt;i:InvokeCommandAction 
            Command=&amp;quot;{Binding StartWatchingForFolder_Renaimer_Command}&amp;quot;/&amp;gt;
      &amp;lt;/i:EventTrigger&amp;gt;
      &amp;lt;i:EventTrigger EventName=&amp;quot;Unchecked&amp;quot;&amp;gt;
          &amp;lt;i:InvokeCommandAction 
            Command=&amp;quot;{Binding StopWatchingForFolder_Renaimer_Command}&amp;quot;/&amp;gt;
       &amp;lt;/i:EventTrigger&amp;gt;
    &amp;lt;/i:Interaction.Triggers&amp;gt; 
&amp;lt;/CheckBox&amp;gt;
&lt;/pre&gt;
  &lt;p&gt;С помощью библиотеки &lt;strong&gt;System.Windows.Interactivity&lt;/strong&gt; удаётся привязать события элемента UI к командам класса ViewModel.&lt;/p&gt;
  &lt;pre&gt;//Начать отслеживать появление изменений в папке
public RelayCommand StartWatchingForFolder_Renaimer_Command
 { get
    {
      return _startWatchingForFolder_Ranaimer_Command ?? 
             (_startWatchingForFolder_Ranaimer_Command
              = new RelayCommand(() =&amp;gt;
              {
                //Проверка на наличие пути
                if (CheckEnteredPath(PathToFilesForAddString_Renamer) == 0)
                {
                  AutoWatchingForFolder = false;
                  return;
                }
                if (watcher == null)
                {
                  watcher = new FileSystemWatcher();
                  watcher.Path = PathToFilesForAddString_Renamer;
                  watcher.NotifyFilter = NotifyFilters.LastAccess
                              | NotifyFilters.FileName 
                              | NotifyFilters.DirectoryName;
                }
                watcher.Changed += (sender, args) =&amp;gt;
                {
                  //Отправка сообщения об изменении состояния файла
                  SendMessageInLogFromWatcher(args);
                };
                watcher.Created += (sender, args) =&amp;gt;
                {
                  //Отправка сообщения об изменении состояния файла
                  SendMessageInLogFromWatcher(args);
                  FileInfo inputFile = new FileInfo(args.FullPath);
                  Thread.Sleep(50);
                  if (RenameFileMethod_Renamer(inputFile) == &amp;quot;errorExceptionCheckIt&amp;quot;)
                  { return; }
                };
                watcher.Deleted += (sender, args) =&amp;gt;
                {
                  //Отправка сообщения об изменении состояния файла
                  SendMessageInLogFromWatcher(args);
                };
                watcher.Renamed += (sender, args) =&amp;gt;
                {
                  //Отправка сообщения об изменении состояния файла
                  SendMessageInLogFromWatcher(args);
                };
                watcher.EnableRaisingEvents = true;
              }));
      }
    }
//Остановить отслеживание изменений в папке
public RelayCommand StopWatchingForFolder_Renaimer_Command
{
 get
   {
    return _stopWatchingForFolder_Ranaimer_Command ?? (_stopWatchingForFolder_Ranaimer_Command = new RelayCommand(() =&amp;gt;
      {
       if (watcher!=null)
        {
         watcher.EnableRaisingEvents = false;
         watcher = null;
        }
      }));
   }
}
&lt;/pre&gt;
  &lt;p&gt;В отслеживании помогает специальный класс &lt;strong&gt;FileSystemWatcher&lt;/strong&gt;, который ожидает поступления уведомления от файловой системы об изменениях и инициализирует при этом события.&lt;/p&gt;
  &lt;p&gt;После создания экземпляра этого класса его нужно настроить&lt;/p&gt;
  &lt;pre&gt;//Создание экземпляра класса
watcher = new FileSystemWatcher();
//Прописываем путь до папки
watcher.Path = PathToFilesForAddString_Renamer;
//Добавляем необходимые фильтры (В зависимости от них система будет выбирать на какие изменения ей нужно реагировать)
watcher.NotifyFilter = NotifyFilters.LastAccess
   | NotifyFilters.FileName 
   | NotifyFilters.DirectoryName;
&lt;/pre&gt;
  &lt;p&gt;Дальше нужно подписаться на события, которые возникают при изменениях в каталоге.&lt;/p&gt;
  &lt;pre&gt;//Событие создания файла в каталоге. Самое нужное нам событие.
watcher.Created += (sender, args) =&amp;gt;
   {
//Отправка сообщения об изменении состояния файла
    SendMessageInLogFromWatcher(args);
    FileInfo inputFile = new FileInfo(args.FullPath);
    Thread.Sleep(50);
    if (RenameFileMethod_Renamer(inputFile) == &amp;quot;errorExceptionCheckIt&amp;quot;)
     { return; }
    };
&lt;/pre&gt;
  &lt;p&gt;Так же здесь есть метод &lt;strong&gt;SendMessageInLogFromWatcher()&lt;/strong&gt; который в качестве входного параметра получает экземпляр класса FileInfo и выводит в окно логов информацию о проведенной операции.&lt;/p&gt;
  &lt;pre&gt;//Отправка сообщения об изменении состояния файла
public void SendMessageInLogFromWatcher(FileSystemEventArgs args)
{
  if (args is RenamedEventArgs)
  {
    DispatcherHelper.CheckBeginInvokeOnUI(() =&amp;gt;
    {
      Messenger.Default.Send(new AddInfoInLogFileMessage()
      {
        MessageForLogFile = &amp;quot;Файл: &amp;quot; + (args as RenamedEventArgs).OldName
                           + &amp;quot; был переименован в &amp;quot; + args.Name,
        TextColorInLog = &amp;quot;#000000&amp;quot;
      });
    });
    return;
  }
  DispatcherHelper.CheckBeginInvokeOnUI(() =&amp;gt;
  {
    Messenger.Default.Send(new AddInfoInLogFileMessage()
    {
      MessageForLogFile = &amp;quot;Файл: &amp;quot; + args.Name + &amp;quot; был &amp;quot; + args.ChangeType,
      TextColorInLog = &amp;quot;#000000&amp;quot;
    });
  });
}
&lt;/pre&gt;
  &lt;p&gt;Класс &lt;strong&gt;DispatcherHelper&lt;/strong&gt; предоставляет возмодность отправлять информацию в виде сообщений между потоками.&lt;/p&gt;
  &lt;p&gt;Можно сказать, что реализация автоматического добавления строки к названию файла, который появляется в папке, завершена.&lt;/p&gt;
  &lt;h2&gt;Удаление строки из названия файла.&lt;/h2&gt;
  &lt;p&gt;Эта часть программы очень похожа на процесс добавления строк, поэтому описывать ее второй раз не вижу смысла. И так получился большой пост, перегруженный большим количеством кода. Как удалять строки можно посмотреть в исходном коде программы.&lt;/p&gt;
  &lt;h2&gt;Итоги&lt;/h2&gt;
  &lt;p&gt;Подведем маленький итог. Было создано простенькое приложение, которое изменяет имена всех файлов в выбранной папке. Удалось даже &lt;s&gt;прикрутить&lt;/s&gt;реализовать паттерн MVVM, такая архитектура пригодится в случае расширения возможностей программы.&lt;/p&gt;
  &lt;p&gt;Спасибо за внимание. По возникающим вопросам пишите в комментарии.&lt;/p&gt;
  &lt;p&gt;И, как обещал ссылка проекта на &lt;a href=&quot;https://github.com/NiGushch/UsefulUtility&quot; target=&quot;_blank&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

</content></entry><entry><id>nigushch:HJ5KRSre4</id><link rel="alternate" type="text/html" href="https://teletype.in/@nigushch/HJ5KRSre4?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=nigushch"></link><title>Программа для добавления/удаления строки к именам файлов в папке. Часть 1.</title><published>2018-12-17T17:55:39.457Z</published><updated>2018-12-19T18:11:39.604Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://teletype.in/files/cb/cbf3cbdb-e2ce-4da3-8d61-2c9068d7d367.png"></media:thumbnail><category term="topic309" label="Проекты"></category><category term="wpf" label="WPF"></category><summary type="html">&lt;img src=&quot;https://teletype.in/files/4e/4e9912d5-dc1b-4e14-b1ae-41095b8901d8.jpeg&quot;&gt;Как-то раз столкнулся с такой проблемой. Понадобилось добавить к именам всех файлов в папке одну и ту же строку, но так как файлов было очень много (10-ки тысяч) вручную это сделать не представлялось возможным. Вот и пришла в голову идея написать маленькую программу, которая добавляет строку к имени файла и может удалять символы, начиная с введенного индекса.</summary><content type="html">
  &lt;p&gt;Как-то раз столкнулся с такой проблемой. Понадобилось добавить к именам всех файлов в папке одну и ту же строку, но так как файлов было очень много (10-ки тысяч) вручную это сделать не представлялось возможным. Вот и пришла в голову идея написать маленькую программу, которая добавляет строку к имени файла и может удалять символы, начиная с введенного индекса.&lt;/p&gt;
  &lt;p&gt;Программу писал на основе технологии WPF. Для того чтобы потренироваться с применением архитектурных паттернов, принял решение реализовать проект с использованием MVVM (о нем расскажу в отдельной статье). Unit тестирование не добавлял, в случае развития проекта (есть идеи добавить еще какой-нибудь функционал) добавлю.&lt;/p&gt;
  &lt;h2&gt;Создание проекта и определение структуры.&lt;/h2&gt;
  &lt;p&gt;В VS создаем новый проект &amp;quot;Приложение WPF&amp;quot;. Через «Диспетчер пакетов NuGet» устанавливаем библиотеку MVVM Ligth (хорошая библиотека, которая создает уже определенную логику и макет проекта). Она нам создаст папку ViewModel, в которой находятся два класса ViewModelLocator (помогает с Binding’ом данных и создает экземпляр класса ViewModel) и MainViewModel (в нем содержится логика для представления MainWindow), они нам нужны, для того чтобы развязать представление от бизнес логики приложения. Добавим так же папки Views и Helpers, в первую переместим все файлы представлений (он у нас пока один), а во второй будут храниться классы, которые помогут отправлять Messages из ViewModel во View.&lt;/p&gt;
  &lt;figure class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/4e/4e9912d5-dc1b-4e14-b1ae-41095b8901d8.jpeg&quot; width=&quot;912&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Таким образом, мы реализовали структуру проекта (в простом варианте, без классов моделей).&lt;/p&gt;
  &lt;h2&gt;Создание представления.&lt;/h2&gt;
  &lt;p&gt;Графический интерфейс у нас будет состоять из двух вкладок:&lt;/p&gt;
  &lt;p&gt;• добавление строк к имени файла&lt;/p&gt;
  &lt;p&gt;• удаление символов из имени файла&lt;/p&gt;
  &lt;p&gt;На рисунке ниже показано, как выглядит первая вкладка&lt;/p&gt;
  &lt;figure class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/3f/3f3f3c91-7bc5-4e3f-87f9-78a952069947.jpeg&quot; width=&quot;896&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;На ней есть поле для ввода пути до папки, в которой будут переименовываться файлы, а справа кнопка для вызова диалогового окна выбора папки.&lt;/p&gt;
  &lt;pre&gt;&amp;lt;Grid&amp;gt;
    &amp;lt;Grid.ColumnDefinitions&amp;gt;
        &amp;lt;ColumnDefinition/&amp;gt;
        &amp;lt;ColumnDefinition Width=&amp;quot;30&amp;quot;/&amp;gt;
    &amp;lt;/Grid.ColumnDefinitions&amp;gt;
    &amp;lt;TextBox Grid.Column=&amp;quot;0&amp;quot; Name=&amp;quot;PathToFolderAddString_tb&amp;quot; 
             Text=&amp;quot;{Binding PathToFilesForAddString_Renamer, 
             Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}&amp;quot;/&amp;gt;
    &amp;lt;Button Grid.Column=&amp;quot;1&amp;quot; Name=&amp;quot;BrowseFolderAddString_btn&amp;quot; Content=&amp;quot;...&amp;quot; 
             Click=&amp;quot;BrowseFolderAddString_btn_OnClick&amp;quot;/&amp;gt;
&amp;lt;/Grid&amp;gt;
&lt;/pre&gt;
  &lt;p&gt;Пришлось использовать класс FolderBrowserDialog из библиотеки System.Windows.Forms, так как в WPF нет встроенного класса с таким диалоговым окном.&lt;/p&gt;
  &lt;p&gt;Код для метода Click кнопки BrowseFolderAddString_btn.&lt;/p&gt;
  &lt;pre&gt;private void BrowseFolderAddString_btn_OnClick(object sender, RoutedEventArgs e)
    {
      FolderBrowserDialog fbd = new FolderBrowserDialog();
      fbd.Description = &amp;quot;Выберите путь до папки с файлами&amp;quot;;
      if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
      {
        PathToFolderAddString_tb.Text = fbd.SelectedPath;
      }
    }
&lt;/pre&gt;
  &lt;p&gt;Ниже расположены три TextBox’а, в которые нужно ввести текст для добавления.&lt;/p&gt;
  &lt;pre&gt;&amp;lt;Label Content=&amp;quot;Добавить текст до:&amp;quot;/&amp;gt;
&amp;lt;TextBox Name=&amp;quot;AddTextBefore_tb&amp;quot; Text=&amp;quot;{Binding StringBeforeFileName_Renamer, 
         UpdateSourceTrigger=PropertyChanged}&amp;quot;/&amp;gt;
&amp;lt;Label Content=&amp;quot;Добавить текст после:&amp;quot;/&amp;gt;
&amp;lt;TextBox Name=&amp;quot;AddTextAfter_tb&amp;quot; Text=&amp;quot;{Binding StringAfterFileName_Renamer,
         UpdateSourceTrigger=PropertyChanged}&amp;quot;/&amp;gt;
&amp;lt;StackPanel Orientation=&amp;quot;Horizontal&amp;quot;&amp;gt;
&amp;lt;Label Content=&amp;quot;Вставить текст на позицию: &amp;quot;/&amp;gt;
&amp;lt;xctk:IntegerUpDown Minimum=&amp;quot;0&amp;quot; Margin=&amp;quot;10 5 0 5&amp;quot; Text=&amp;quot;{Binding InputPosition_Renamer,
         UpdateSourceTrigger=PropertyChanged}&amp;quot;/&amp;gt;
&amp;lt;/StackPanel&amp;gt;
&amp;lt;TextBox Name=&amp;quot;InsertTextOnPosition_td&amp;quot; Text=&amp;quot;{Binding InsertTextOnPosition_Renamer,
         UpdateSourceTrigger=PropertyChanged}&amp;quot;/&amp;gt;
&lt;/pre&gt;
  &lt;p&gt;Справа Button для выполнения переименования и CheckBox, который запускает непрерывное сканирование на появление событий связанных с выбранной папкой (такие события как: добавление, удаление, переименование файлов).&lt;/p&gt;
  &lt;pre&gt;&amp;lt;GroupBox Header=&amp;quot;Запуск переименовывания&amp;quot; Grid.Column=&amp;quot;1&amp;quot; Margin=&amp;quot;5&amp;quot; Padding=&amp;quot;5&amp;quot;&amp;gt;
     &amp;lt;StackPanel Margin=&amp;quot;10&amp;quot;&amp;gt;
         &amp;lt;Button Name=&amp;quot;RenameFilesOneTime_btn&amp;quot; Command=&amp;quot;{Binding RenameFiles_Renaimer_Command}&amp;quot; 
                 Content=&amp;quot;Переименовать файлы&amp;quot; /&amp;gt;
         &amp;lt;CheckBox Margin=&amp;quot;0 10 0 10&amp;quot; IsChecked=&amp;quot;{Binding AutoWatchingForFolder,
                 UpdateSourceTrigger=PropertyChanged}&amp;quot;&amp;gt;
         &amp;lt;TextBlock Text=&amp;quot;Автоматически переименовывать файлы при появлении в папке&amp;quot; 
                 TextWrapping=&amp;quot;Wrap&amp;quot;/&amp;gt;
             &amp;lt;i:Interaction.Triggers&amp;gt;
                &amp;lt;i:EventTrigger EventName=&amp;quot;Checked&amp;quot;&amp;gt;
                   &amp;lt;i:InvokeCommandAction 
                       Command=&amp;quot;{Binding StartWatchingForFolder_Renaimer_Command}&amp;quot;/&amp;gt;
                &amp;lt;/i:EventTrigger&amp;gt;
                &amp;lt;i:EventTrigger EventName=&amp;quot;Unchecked&amp;quot;&amp;gt;
                   &amp;lt;i:InvokeCommandAction 
                       Command=&amp;quot;{Binding StopWatchingForFolder_Renaimer_Command}&amp;quot;/&amp;gt;
                   &amp;lt;/i:EventTrigger&amp;gt;
                &amp;lt;/i:Interaction.Triggers&amp;gt;
         &amp;lt;/CheckBox&amp;gt;
      &amp;lt;/StackPanel&amp;gt;
&amp;lt;/GroupBox&amp;gt;
&lt;/pre&gt;
  &lt;p&gt;Все изменения будут отображаться в логах.&lt;/p&gt;
  &lt;p&gt;При добавлении новых файлов в папку они будут автоматически переименовываться по заданному правилу.&lt;/p&gt;
  &lt;p&gt;Вторая вкладка выполнена в аналогичном стиле.&lt;/p&gt;
  &lt;figure class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/37/37121979-ee70-433f-9145-ee958b866f03.jpeg&quot; width=&quot;893&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Есть два TextBox для ввода начального индекса и количества удаляемых символов. Также есть возможность выбора порядка удаления, с начала или с конца имени файла.&lt;/p&gt;
  &lt;p&gt;Код представлен ниже.&lt;/p&gt;
  &lt;pre&gt;&amp;lt;Grid&amp;gt;
    &amp;lt;Grid.ColumnDefinitions&amp;gt;
        &amp;lt;ColumnDefinition/&amp;gt;
        &amp;lt;ColumnDefinition/&amp;gt;
    &amp;lt;/Grid.ColumnDefinitions&amp;gt;

&amp;lt;!--Путь к файлам и настройка переименования--&amp;gt;
    &amp;lt;GroupBox Header=&amp;quot;Настройки&amp;quot; Margin=&amp;quot;5&amp;quot; Padding=&amp;quot;2&amp;quot;&amp;gt;
       &amp;lt;StackPanel&amp;gt;
           &amp;lt;Label Content=&amp;quot;Путь к файлам:&amp;quot;/&amp;gt;
           &amp;lt;Grid&amp;gt;
              &amp;lt;Grid.ColumnDefinitions&amp;gt;
                 &amp;lt;ColumnDefinition/&amp;gt;
                 &amp;lt;ColumnDefinition Width=&amp;quot;30&amp;quot;/&amp;gt;
              &amp;lt;/Grid.ColumnDefinitions&amp;gt;
              &amp;lt;TextBox Grid.Column=&amp;quot;0&amp;quot; Name=&amp;quot;PathToFolderDeleteString_tb&amp;quot;
                      Text=&amp;quot;{Binding PathToFilesForDeleteString_Renamer,
                      Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}&amp;quot;/&amp;gt;
              &amp;lt;Button Grid.Column=&amp;quot;1&amp;quot; Name=&amp;quot;BrowseFolderDeleteString_btn&amp;quot; Content=&amp;quot;...&amp;quot; 
                  Click=&amp;quot;BrowseFolderDeleteString_btn_OnClick&amp;quot;/&amp;gt;
            &amp;lt;/Grid&amp;gt;
            &amp;lt;Label Content=&amp;quot;Порядок удаления:&amp;quot;/&amp;gt;
            &amp;lt;StackPanel Orientation=&amp;quot;Horizontal&amp;quot;&amp;gt;
                &amp;lt;RadioButton GroupName=&amp;quot;turn&amp;quot; Content=&amp;quot;Начало=&amp;gt;Конец&amp;quot; Margin=&amp;quot;5&amp;quot; IsChecked=&amp;quot;{Binding BeginningOrEnd}&amp;quot; /&amp;gt;
                &amp;lt;RadioButton GroupName=&amp;quot;turn&amp;quot; Content=&amp;quot;Конец=&amp;gt;Начало&amp;quot; Margin=&amp;quot;5&amp;quot;/&amp;gt;
            &amp;lt;/StackPanel&amp;gt;
            &amp;lt;Label Content=&amp;quot;Начать с:&amp;quot;/&amp;gt;
            &amp;lt;TextBox Name=&amp;quot;StartPoint_tb&amp;quot; Text=&amp;quot;{Binding StartPointForDelete_Renaimer}&amp;quot;/&amp;gt;
            &amp;lt;Label Content=&amp;quot;Сколько удалять:&amp;quot;/&amp;gt;
            &amp;lt;TextBox Name=&amp;quot;NumCharForDelete_tb&amp;quot; Text=&amp;quot;{Binding NumOfCharForDelete_Renaimer}&amp;quot;/&amp;gt;
       &amp;lt;/StackPanel&amp;gt;
    &amp;lt;/GroupBox&amp;gt;

&amp;lt;!--Запуск переименования--&amp;gt;
&amp;lt;GroupBox Header=&amp;quot;Запуск переименовывания&amp;quot; Grid.Column=&amp;quot;1&amp;quot; Margin=&amp;quot;5&amp;quot; Padding=&amp;quot;5&amp;quot;&amp;gt;
     &amp;lt;StackPanel Margin=&amp;quot;10&amp;quot;&amp;gt;
        &amp;lt;Button Name=&amp;quot;RenameFilesDeleteString_btn&amp;quot; Command=&amp;quot;{Binding DeleteStringFromFileName_Command}&amp;quot; 
                Content=&amp;quot;Переименовать файлы&amp;quot; /&amp;gt;
     &amp;lt;/StackPanel&amp;gt;
&amp;lt;/GroupBox&amp;gt;
&amp;lt;/Grid&amp;gt;
&lt;/pre&gt;
  &lt;p&gt;На этом этапе заканчивается процесс создания визуальной части приложения. Если есть какие-то вопросы, то пишите в комментарии&lt;/p&gt;
  &lt;p&gt;Во второй части я расскажу как реализовать класс ViewModel и логику выполнения переименования файлов. Ссылка на исходный код программы будет там же.&lt;/p&gt;

</content></entry><entry><id>nigushch:S1I2mEelN</id><link rel="alternate" type="text/html" href="https://teletype.in/@nigushch/S1I2mEelN?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=nigushch"></link><title>Мой первый пост.</title><published>2018-12-13T19:31:58.292Z</published><updated>2018-12-17T16:24:27.126Z</updated><summary type="html">Приветствую вас, друзья!</summary><content type="html">
  &lt;p&gt;Приветствую вас, друзья!&lt;/p&gt;
  &lt;p&gt;Первый пост писать всегда сложно, много что хочется рассказать, но обо всем по порядку.&lt;/p&gt;
  &lt;p&gt;Меня зовут Николай и мне 25 лет. Я окончил университет с красным дипломом (инженер радиотехник), и пошел работать по специальности (как я думал). Примерно год назад стало понятно, что выбранная профессия мне не нравится. Я не чувствовал, что развиваюсь как профессионал. Нужно было что-то менять.&lt;/p&gt;
  &lt;p&gt;В университете мне не нравилось программирование, казалось, что оно очень сложное и не постижимое. Но время шло, сознание менялось, появился интерес (может потому, что все таки пришлось программировать). Только язык программирования был подстать специальности, инженерный (это был LabView). Хотя и получалось на нем работать и довольно не плохо, даже пару программ удалось реализовать, не лежала душа к нему, хотелось что-то более общераспространенное, да и когда появились мысли об уходе стал больше смотреть в сторону &amp;quot;С&amp;quot; подобных языков. И тут мой взгляд упал на детище компании Microsoft, а именно на языке C#.&lt;/p&gt;
  &lt;p&gt;Начал с изучения основ по книге Троелсена &amp;quot;&lt;a href=&quot;https://www.ozon.ru/context/detail/id/137598683/&quot; target=&quot;_blank&quot;&gt;Язык программирования C# 5.0 и платформа .NET 4.5&lt;/a&gt;&amp;quot;, повторял все изложенные там примеры, но все равно было не легко все понять с первого раза (особенно многопоточность и работу с делегатами). Параллельно решал задачки на &lt;a href=&quot;http://CodeWars.com&quot; target=&quot;_blank&quot;&gt;CodeWars&lt;/a&gt;. На это ушло парочка месяцев. Оставался вопрос, где искать практику, ведь использую только книги научиться невозможно.&lt;/p&gt;
  &lt;p&gt;Захотел попробовать себя в разработке мобильных приложений. Благо у .Net есть технология Xamarin, которая позволяет создавать как кроссплатформенные, так и нативные приложения для мобильных устройств. Но позанимался этим не долго, где то 2 месяца пока был в командировке, сделал небольшой калькулятор для Android. А когда вернулся на работу уже не было времени на Xamarin, да и технология то не сильно востребована.&lt;/p&gt;
  &lt;p&gt;Далее приступил к разработке приложений для ПК с использованием технологии WPF. Тут то уже намного дольше удалось поработать, до сих пор делаю небольшие приложения (позже напишу про процесс их создания). Мне она понравилась за счёт возможности быстро и легко создавать красивый адаптивный интерфейс, использовать архитектурный паттерн MVVM и достаточно удобно работать с графикой. Но все же душа у меня тянулась к Веб разработке...&lt;/p&gt;
  &lt;p&gt;Во время другой командировки мне удалось изучить HTML, CSS, JavaScript для создания frontend, а так же начал читать про возможности Asp.Net MVC. Параллельно с обучением работал над проектом по созданию движка для блога, поэтому все что удавалось узнать сразу применял на практике. Очень хотелось доделать его до конца и на его основе вести свой блог)) но так до конца не получилось его реализовать, времени не хватило... Хотя сейчас я бы его уже делал совсем по другому. Наверное в скором времени переделаю и выложу здесь описание.&lt;/p&gt;
  &lt;p&gt;Так же в рамках открытого мастер-класса сделал проект телеграмм бота на C#. По запросу города он отправлял погоду, которую подгружал с сервисов. Тоже интересный проект, нужно будет ещё парочку ботов сделать)&lt;/p&gt;
  &lt;p&gt;В целом мне удалось попробовать много технологий. Больше всего понравилась web backend разработка, в направлении которой и дальше буду развиваться. В течение 2019 года хочу сменить работу и уйти в программисты про этот путь и буду вам рассказывать.&lt;/p&gt;
  &lt;p&gt;В блоге буду делиться своим опытом, мыслями, проектами, интересными статьями и всякими полезными штуками.&lt;/p&gt;
  &lt;p&gt;Я рад новым знакомствам и общению, пишите отзывы здесь или обращайтесь напрямую в телеграмм (&lt;a href=&quot;http://t.me/vncntbrown&quot; target=&quot;_blank&quot;&gt;мой аккаунт&lt;/a&gt;). Так же можете подписаться на наш канал в телеграмме - &lt;a href=&quot;http://t.me/maddevelop&quot; target=&quot;_blank&quot;&gt;Mad Develop&lt;/a&gt;, там мы выкладываем статьи, шутейки и краткие истории.&lt;/p&gt;
  &lt;p&gt;Контакты:&lt;/p&gt;
  &lt;ol&gt;
    &lt;li&gt;&lt;a href=&quot;http://t.me/vncntbrown&quot; target=&quot;_blank&quot;&gt;Telegram&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://github.com/NiGushch&quot; target=&quot;_blank&quot;&gt;GitHub&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://www.linkedin.com/in/николай-гущарин-8488b4159/&quot; target=&quot;_blank&quot;&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://moikrug.ru/nigushch&quot; target=&quot;_blank&quot;&gt;Мой круг&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;

</content></entry></feed>