• Как сделать привязку данных по выбору?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Можно попробовать сделать третье свойство, которое в геттере будет получать нужное свойство.
    Ответ написан
    6 комментариев
  • Как переписать OdbcCommand для массовой вставки?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    А сама база не сможет выполнить запрос вставки по выборке?
    insert into org_iogjt_import_org_gate_job_title (iogjt_jobtitle_id, iogjt_jobtitle_name, iogds_datasource_id) 
        SELECT KSLP, NSLP, 1 FROM SLP WHERE KSLP <> 0 ORDER BY KSLP ASC

    Тогда можно просто выполнить запрос, без цикла и без параметров.
    Ответ написан
  • Переход с C++ на C#?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    С C++ на C# будет гораздо проще, чем было бы наоборот. Не переживайте, у вас получится, через месяц-другой вы будете знать шарп не хуже, чем сейчас плюсы.
    Я рекомендую книгу Троелсена, потому что он подробнейшим образом пишет само описание языка, как писать код на c#, а не учит программированию, насколько я понял, вам это не нужно - алгоритмы, ООП и пр. вы уже знаете.
    Ответ написан
    Комментировать
  • Как переместить файлы по заданному условию?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Вторым аргументом указывается не папка, а полный путь к новому файлу, с именем.
    var filename = Path.GetFileName(s);
    File.Move(s, pathA + "\\" + filename);
    Ответ написан
    Комментировать
  • Как узнать номер рабочего стола на котором окно?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Если вам нужно именно номер монитора, а не рабочего стола, то вам нужен класс System.Windows.Forms.Screen, который имеет много полезного. Например, Screen.FromControl(), Screen.FromHandle() и пр. Или можно использовать свойство AllScreens, хранящее все мониторы системы.
    Тут есть нюанс - FromHandle берёт не верхнюю левую точку окна, а середину верхней границы окна. Смотрите, что вам нужно.
    И ещё один нюанс - номера мониторов в списке AllScreens могут не совпадать с номером монитора в настройках экранов Windows. Этот виндовский номер монитора я так и не смог найти. Виндовские номера зависят порта видеокарты, к которому они подключены.
    Ответ написан
    2 комментария
  • Как загрузить UserControl при клике на элемент ListBox?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Вам нужно просто связать датаконтекст групбоксов с выделенным элементом списка. Всё остальное сделает WPF.
    <ListBox ItemsSource="{Binding DevList}" SelectedItem="{Binding SelectedElement}" />
    <GroupBox DataContext="{Binding SelectedElement}">
    </GroupBox>
    <GroupBox DataContext="{Binding SelectedElement.Subelement1}">
    </GroupBox>


    Чтобы это заработало, то нужно сделать так, чтобы DevList был список объектов, а не строк. Создайте класс (вьюмодель) для ваших элементов списка. В нём можно хранить те свойства, которые вы хотите показывать в групбоксах. То есть, в списке элементов хранятся ваши объекты, а потом они же указываются датаконтекстом в другие контролы (групбоксы).

    В таком случае хорошо сделать во вьюмодели реализацию INotifyPropertyChanged.
    Ответ написан
  • Как остановить поток?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Останавливать поток нужно не убиванием его, а остановкой, желательно - изнутри. А чтобы это можно было сделать нужно передать внутрь токен останова. Сам останов ничего не делает, но он используется внутри тела потока для отмены или аварийного завершения. Этот токен передастся в Worker, в котором нужно будет проверять наличие останова с помощью cancellationToken.IsCancellationRequested. Если в воркере используется цикл, то проверять можно в каждой итерации.

    var formWait = new FormWait(cancellationToken => 
    {
        foreach(var item in _items)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return;
            }
            item.DoWork();
        }
    });


    wait.Stop = delegate ()
          {
            var source = _tokenSource;
            if (source != null)
            {
                source.Cancel();
                source.Dispose();
                _tokenSource = null;
            }
          };
          myThread.Start();
    
    В форме:
        public Action<CancellationToken> Worker { get; } // добавляем ссылку на токен останова
        public Action Stop { get; set; }
        private CancellationTokenSource _tokenSource;
        public FormWait(Action<CancellationToken> worker)
        {
          InitializeComponent();
          if (worker == null)
            throw new ArgumentNullException();
          Worker = worker;
        }
        protected override void OnLoad(EventArgs e)
        {
          base.OnLoad(e);
          _tokenSource?.Dispose();
          _tokenSource = new CancellationTokenSource();
          var cancellationToken =  = _tokenSource.Token;
          Task.Factory.StartNew(() => Worker(cancellationToken ))
              .ContinueWith(t => { this.Close(); }, TaskScheduler.FromCurrentSynchronizationContext());
        }
    
        private void button1_Click(object sender, EventArgs e)
        {
          Console.WriteLine("Stop");
          Stop();
        }


    Возможно, хорошо сделать таск с возвращаемым результатом, например
    public Func<CancellationToken, bool> Worker { get; }
    
    Task.Factory.StartNew<bool>(() => Worker(cancellationToken))
    .ContinueWith(t => { if (t.Result) this.Close(); }, TaskScheduler.FromCurrentSynchronizationContext());
    Ответ написан
    Комментировать
  • В чем разница между переопределением (override), от перекрытия (new), наследуемого метода?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Сначала отвечу на третий вопрос.
    Чтобы понять, в чём разница между переопределением и перекрытием, нужно понять, как программа выбирает, какой вариант метода нужно вызвать, в зависимости от реального типа объекта.
    Компилятор создаёт таблицу всех виртуальных методов класса (в том числе, переопределённых, потому что они тоже виртуальные) и указывает, в каком типе они обозначены. При вызове виртуального метода берётся реальный тип объекта и выбирается нужный вариант реализации метода.
    Если вы указываете в классе-наследнике метод с ключевым словом new, то этот метод перестаёт быть переопределением метода базового класса, и этот метод не добавляется в ту таблицу переопределений. Значит, при вызове метода поиск по типу объекта не найдёт метод, отмеченный new (его же нет в таблице), и попытается найти ближайший метод.
    Обратите внимание, что новый перекрываемый метод тоже может быть указан с ключевым методом virtual, то есть, он тоже попадёт в таблицу виртуальных методов, но как бы в другую таблицу, тем самым создавая новую иерархию реализаций.

    2. Когда использовать переопределение, а когда перекрытие?
    Обычно нужно переопределение, перекрытие редко кому нужно. Если нужна отдельная реализация у конкретного наследника, то (иногда) можно сделать метод с другим именем, и вызывать напрямую, а не через вызов виртуальных методов. Если это всё-таки необходимо (перекрыть метод), то нужно понимать, что вызвать такой метод через ссылку на базовый класс не получится (без приведения к нужному типу).

    Интересно, что в Java все методы виртуальные, и нет возможности перекрыть (но не переопределить) базовый метод, как это можно в c#.

    1. Как можно визуализировать эти подходы?
    Этот вопрос непонятен. В графическом описании иерархии классов? В UML, насколько я помню, виртуальные методы пишутся курсивом. Значит, перекрытый метод будет обычным, не курсивным шрифтом.
    Ответ написан
    2 комментария
  • Не появляется роутер в списке wifi-устройств. Как исправить?

    lexxpavlov
    @lexxpavlov Автор вопроса
    Программист, преподаватель
    На роутере отключил автонастройку канала и установил самый слабозагруженный канал (нашёл через Wi-fi анализатор), проблема исчезла. Посмотрю, что будет дальше...
    Странно, что на других устройствах тот же канал не приводил проблемам..
    Ответ написан
    Комментировать
  • Фокус с делегатом. Как его исполнить?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    namespace DelegateDemo
    {
        public delegate string DemoDel(string s);
       
        class Program
        {  
            static void Main(string[] args)
            {
                ParamMethod(DelLink); // передача ссылки на метод DelLink в ParamMethod
                ParamMethod(s => "(" + s + ")"); // передача анонимной функции в ParamMethod
                Console.ReadKey();
            }
    
            static bool ParamMethod(DemoDel d)
            {
                if(d("что угодно") == "2")
                {
                    Console.WriteLine("делегат вернул 2");
                }
                if(d("5") == "(5)" && d("100500") == "(100500)")
                {
                    Console.WriteLine("делегат обернул число в скобки");
                }
            }
            static string DelLink(string s)
            {
                return "2";
            }
        }
    }
    Ответ написан
    3 комментария
  • Как правильно "Собрать решение"?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    А если всю папку C:\Users\pupkin\source\repos\WindowsFormsApp1\WindowsFormsApp1\bin\Debug скопировать и запускать экзешник оттуда?
    При создании готовой программы, лучше выбрать конфигурацию сборки Release, и тогда вся папка C:\Users\pupkin\source\repos\WindowsFormsApp1\WindowsFormsApp1\bin\Release станет дистрибутивом программы, особенно, все dll-ки. Можно попытаться убрать из папки "лишние" файлы, но .exe и .dll все обычно нужны.
    Ответ написан
    8 комментариев
  • Как назвать переменную?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    MonetizationType - потому что это не дистрибуция, и уж точно не price (даже не priceType)
    Ответ написан
  • C#. Как правильно получить список файлов из папки в нужном порядке?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    В Windows уже есть готовая функция, которая выполняет натуральное сравнение строк, лучше использовать её. Эта функция разбивает строку на числовые и строковые части и ищет эти части друг с другом, причём числовые части сравнивает как числа, а строковые - алфавитно.

    var testFiles = Directory.EnumerateFiles(solutionDirectory + @"\samples");
    
    var sortedTestFiles1 = testFiles.OrderBy(x => x, new NaturalComparer());
    // или
    var sortedTestFiles2 = testFiles.ToList();
    sortedTestFiles2.Sort(new NaturalComparer());
    
    /// <summary>
    /// Натуральное сравнение строк
    /// </summary>
    public class NaturalComparer : IComparer<string>
    {
        /// <summary>
        /// Вызов WinApi-функции для натурального сравнения строк
        /// </summary>
        [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
        private static extern int StrCmpLogicalW(string psz1, string psz2);
    
        /// <summary>
        /// Натуральное сравнение строк
        /// </summary>
        /// <param name="x">Первая строка</param>
        /// <param name="y">Вторая строка</param>
        /// <returns>Сравнивает две строки, возвращая -1, 0 или 1</returns>
        public static int Compare(string x, string y)
        {
            return StrCmpLogicalW(x, y);
        }
    
        /// <summary>
        /// Натуральное сравнение строк
        /// </summary>
        /// <param name="x">Первая строка</param>
        /// <param name="y">Вторая строка</param>
        /// <returns>Сравнивает две строки, возвращая -1, 0 или 1</returns>
        int IComparer<string>.Compare(string x, string y)
        {
            return StrCmpLogicalW(x, y);
        }
    }
    Ответ написан
    1 комментарий
  • C# WPF почему при Window.Left = 0 между границей экрана и окном появляется пустое пространство?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Это хром окна (WindowChrome), обычно выглядит как тень вокруг окна, является частью окна, поверх клиентской частью. Обычно размер хрома 7px.
    https://docs.microsoft.com/ru-ru/dotnet/api/system...

    Хром отключается при указании окна в развёрнутое состояние (Maximized). А также, можно указать WindowStyle.None окну, тогда неклиентская часть отключится.
    Ответ написан
    Комментировать
  • Чем можно заменить интерполяцию строк в C# 5?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    public void Print(string str)
    {
          Console.WriteLine(string.Format("{0} {1} Ok!", DateTime.Now, str));
    }
    Ответ написан
    3 комментария
  • Почему не добавляет элемент в список?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Вероятно, вы где-то пересоздаёте список meet. Поставьте readonly на поле meet (а ещё лучше, переименовать её на MeetingsList)
    public readonly List<Meetings> MeetingsList = new List<Meetings>();

    Это предотвратит случайное перезаписание переменной.

    >foreach (Meetings meet in meet)
    Тут ошибка в коде, нельзя создать переменную-счётчик цикла Meetings meet, потому что переменная с именем meet уже есть. Если ошибка здесь не возникает, то, скорее всего, в какой-то из двух имён вместо английской "e" стоит русская "е".
    Ответ написан
    4 комментария
  • Как загрузить с помощью include других уровней данные с помтощью entity fraimwork?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    В одной Include можно сразу показывать несколько вложенных связей, тогда все промежуточные тоже подключатся:
    return (from e in db.Position
        .Include(p => p.Operations.Select(o => o.Transition.Select(t => t.RiggingTransition)))
        .Include(p => p.Operations.Select(o => o.MaterialOperation))
        where ...
        select e).ToList();

    В данном случае в Position должны подключиться MaterialOperation и Transition, в котором подключатся RiggingTransition
    Ответ написан
    Комментировать
  • Как вы находите идеи домашних проектов?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Классика для поднятия скилла генерации идей: креативность - это скилл, навык, и его нужно развивать. Каждый день придумывайте 10 идей, абсолютно любых, не думая о возможности реализации. Но обязательно каждый день и минимум 10 идей.
    Через несколько дней можно взглянуть на список за один день и отсортировать по возможности реализации или по нравится/не нравится. Таким образом возникнет обратная связь, и через время идеи станут более реалистичными.
    Если так делать, то через пару месяцев скилл креативности разовьётся хорошо.

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

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Можно сделать шаблоны DataTemplate, которые изменят шаблон нужного типа:
    <Window x:Class="TestApp.MainWindow"
            xmlns:testApp="clr-namespace:TestApp"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <DataTemplate DataType="{x:Type testApp:TestInt}">
                <TextBlock Text="{Binding Value}" Background="Red"/>
            </DataTemplate>
            <DataTemplate DataType="{x:Type testApp:TestStr}">
                <TextBlock Text="{Binding Value}" Background="Yellow"/>
            </DataTemplate>
        </Window.Resources>
        <StackPanel>
                <ContentControl Content="{Binding Test1}"/>
                <ContentControl Content="{Binding Test2}"/>
                <ListBox ItemsSource="{Binding TestList}"/>
        </StackPanel>
    </Window>

    public class TestInt
    {
        public int Value { get; set; }
    }
    public class TestStr
    {
        public string Value { get; set; }
    }
    public partial class MainWindow : Window
    {
        public TestInt Test1 { get; set; }
        public TestStr Test2 { get; set; }
        public List<object> TestList { get; set; } 
    
        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
            Test1 = new TestInt { Value = 123 };
            Test2 = new TestStr { Value = "asd" };
            TestList = new List<object> { Test1, Test2 };
        }


    Чтобы даташаблоны автоматически подключались, тип нужно указывать через DataType="{x:Type testApp:TestInt}", а не через DataType="testApp:TestInt"
    Ответ написан
    Комментировать