Задать вопрос
Ответы пользователя по тегу C#
  • Каков вектор развития legacy-проекта на WinForms?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    Многое зависит от внутренней архитектуры решения, зависимостей, а так же целей и задач, которые вы этим процессом хотите решить. Если вся логика разделена на отдельные модули, то портировать проект на более современные версии .Net будет не очень больно. Но всё равно будет больно. Например, если бизнес-логика и интерфейс чётко разделены — то после разработки нового интерфейса на WPF/Avalonia внедрить всю эту логику будет относительно несложно. А вот если там всё в одной куче — процесс портирования равносилен разработке решения с нуля. Если бюджет позволяет и это решит какие-то ваши текущие задачи — то он вполне имеет смысл быть. Обычно в WinForms всё в одной куче и для новой платформы надо просто всё переписать с нуля. В WPF и иже с ним обычно используют паттерн MVVM, а не MVP. Так что внедрять MVP в WinForms проект не имеет особого смысла — лучше сразу MVVM с прицелом на полноценный переход на WPF. При условии, конечно, дальнейшего развития проекта и наращивания функционала. Если же глобальная цель проекта просто исправление багов и иногда правка функционала — то нет никакого смысла что-то делать. Разве что рефакторинг и детальное документирование, если всё не очень там хорошо с этим.
    Ответ написан
    Комментировать
  • Как универсализировать обычный ViewList в WPF C# XAML?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    string. У вас файл текстовый — вот и используйте как есть.
    Ответ написан
    Комментировать
  • Как проверить, наследует ли объект в обобщённом методе?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    Получить список интерфейсов объекта из его типа и проверить есть ли среди них нужный вам универсальный интерфейс:
    if (item != null
        && item.GetType().GetInterfaces().Any(
            i => i.IsGenericType
            && i.GetGenericTypeDefinition() == typeof(IEnumerable<>))
        )
    {
        IEnumerable<object> collection = (IEnumerable<object>)item;
    }
    Ответ написан
    3 комментария
  • Как включить множество опций публикации в Visual Studio 2022?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    У вас приложение на платформе .Net Framework (версия 4.8.1 или более ранняя) и там вот такой вот мастер публикации. А вот для более новых платформ — .Net 6.0, 8.0 и 9.0 мастер другой и с другими опциями. Там у него конфигурация в виде стандартного xml файла. Если вы хотите использовать более новый мастер — то вам надо мигрировать ваше приложение на более новый .Net.
    Ответ написан
    Комментировать
  • На сколько практично разделять логику загрузки данных?

    VoidVolker
    @VoidVolker Куратор тега JavaScript
    Dark side eye. А у нас печеньки! А у вас?
    "Правильность" зависит от точки зрения, требований, ограничений и прочих особенностей решения. Ваш код решает вашу проблему? Удовлетворяет вашим требованиям, предъявляемым к нему? Значит всё отлично. Если нет - то тут уже надо думать и искать более правильное решение по конкретным критериям конкретного проекта.
    Ответ написан
    Комментировать
  • Как настроить полосу прокрутки, чтобы срабатывала только при наведении на неё?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    Через перехват оконного сообщения WM_MOUSEWHEEL на уровне окна и проверку либо координат курсора (над полосой он прокрутки или нет), либо, что правильнее в вашем случае - проверять нажат ли контрол или нет (т.е. масштабирование это или нет):
    public class MyForm : Form
    {       
        protected override void WndProc(ref Message m)
        {           
            if(m.Msg == WM_MOUSEWHEEL) 
            {
                // ...
                return;
            }; 
            base.WndProc(ref m);
        }
    }
    Ответ написан
    Комментировать
  • Как правильно добавить переменную?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    - int izgib = random.Next(izi_ot, izi_do);
    + double izgib = random.Next(izi_ot, izi_do)/10.0;
    Ответ написан
    2 комментария
  • Zenject зачем добавлять к SceneLoader наследование от ISceneLoader?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    Затем, что интерфейс реализует какой-то определённый функционал. Если класс не реализует интерфейс - то и использовать функционал интерфейса не получится.

    Zenject зачем добавлять к SceneLoader наследование от ISceneLoader

    Для реализации данного интерфейса, чтобы который потом кто-то мог использовать.

    чтобы потом указывать ISceneLoader как тип

    Нет, чтобы работать конкретно с функционалом данного интерфейса.

    хотя если указать просто SceneLoader как тип ничего не изменится

    Изменится: данный интерфейс будет недоступен. Да, можно объявить одноименные функции, поля и свойства, но интерфейсом это уже не будет. И, соответственно, те, кому нужен будет именно этот интерфейс не сможет его использовать, т.к. класс не реализует данный интерфейс.

    Например, у вас может быть группа разных класса реализующих определённый интерфейс. И вам надо что-то сделать с несколькими экземплярами этих нескольких классов. Можно для каждого сделать по переменной и отдельно для каждого сделать нужную операцию. А можно сделать список интерфейсов и спокойно работать с объектами через интерфейс. Аналогично и для всех других применений. Интерфейс - это прежде всего соглашение о реализации какого-то определённого функционала и его использование.
    Пример кода
    public interface IFoo
    {
        public string Name { get; set; }
    }
    
    public class Bar1(string name) : IFoo
    {
        public string Name { get; set; } = name;
    }
    
    public class Bar2(string name) : IFoo
    {
        public string Name { get; set; } = name;
    }

    List<IFoo> list = [
        new Bar1("Bar 1"),
        new Bar2("Bar 2")
    ];
    
    foreach (IFoo foo in list)
    {
        Console.WriteLine(foo.Name);
    }

    Результат:
    Bar 1
    Bar 2

    Вообще, рекомендую почитать литературу про ООП и интерфейсы в частности. Например: https://metanit.com/sharp/tutorial/3.9.php
    Ответ написан
    Комментировать
  • Как правильно извлечь из БД Uri для отображения картинки в DataGrid (C# WPF)?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    public System.Windows.Media.ImageSource Source { get; set; }

    https://learn.microsoft.com/en-us/dotnet/api/syste...
    Ну и у вас в коде же правильное решение:

    TestImage2.Source = new BitmapImage(LoadedUri);

    Т.е., вам надо конвертер не в Uri, а в тип BitmapImage. Ну или просто завести сразу свойство нужного типа.

    Кроме того, вот тут у вас ошибка во втором параметре конвертера, который противоречит касту:
    var LoadedUri = (Uri)stringToUriConverter.Convert(a, typeof(BitmapImage), null, CultureInfo.CurrentCulture);


    Там должен быть тип в который происходит конвертация. Ну и вообще конвертер лучше реализовывать полностью со всеми проверками и типами.
    Ответ написан
    1 комментарий
  • Как добавить данные из БД в отредактированный DataGrid (C# WPF)?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    DataGrid -> Properties -> AutoGenerateColumns
    А вообще, дата-грид и многие другие сложные контролы в WPF - то ещё веселье. Посмотрите в сторону AvaloniaUI. Ну а если всё же захотите сделать что-то чуть сложнее стандартных примеров из мана со стандартными контролами - то их шаблоны всё равно придётся переделывать, а местами реализовывать тот же функционал, но работающий правильно, а не в стиле индусов. Вот как-то так, например: GridTable.cs - таблица на базе обычного Grid с добавленными свойствами шаблонов для заголовков и ячеек, а так же своим движком для рендернинга таблицы (строк, столбцы, заголовки).
    Ответ написан
    2 комментария
  • Как исправить ошибку CS0019 в Unity?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    Написано же, что складывать текст и флоат нельзя. Очевидно, что вы тут перепутали переменные. Думаю, вполне ясно, что вместо текстовой тут должна быть другая переменная?
    Ответ написан
    2 комментария
  • Как распознать клавишу Alt в терминале?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    Learn / Windows / Apps / Win32 / API / Keyboard and Mouse Input / Winuser.h / GetKeyState():
    https://learn.microsoft.com/en-us/windows/win32/ap...
    Ответ написан
    Комментировать
  • Как правильно обрабатывать исключения в WPF приложении?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    1. Да, надо. Нет, все исключения в Main поймать нельзя.
    2. Есть несколько вариантов:
      1. Сообщение в стандартном WPF контроле в рамках основного окна (типа стандартного сообщения или всплывающего контрола).
      2. Стандартное WinAPI сообщение.
      3. Отдельное окно с WPF контролом и деталями сообщения.
    3. Да, вполне нормальный вариант.

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

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

    Реальный пример базового класса для исключения с локализацией:
        /// <summary>
        /// Localized exception
        /// </summary>
        /// <param name="stringId">i18n string Id</param>
        /// <param name="args">String arguments for format</param>
        public class I18nException(string stringId, object[] args)
            : Exception(
                string.Format(
                    I18n($"{ExceptionId} {stringId}"),
                    args))
        {
            public readonly object[] Args = args;
            public readonly string StringId = stringId;
            private const string ExceptionId = "Exception";
        }

    I18n(string str) - функция для получения локализованной строки для текущего языка приложения.
    Ну и далее наследуем свои исключения от этого базового типа:
        public class ElementNotFoundException(Type type, string name)
            : I18nException(
                "Element not found",
                [type.FullName, name]
            )
        {
            public readonly string ElementName = name;
            public readonly Type ElementType = type;
        }
    (тыц).
    Ответ написан
    2 комментария
  • Как влиять на окно выводя его за пределы экрана?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    Сравнить координаты и размеры окна с координатами и размером текущего экрана.
    Ответ написан
    Комментировать
  • Какой самый быстрый способ поиска файлов на сетевом диске?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    Использовать индексацию на стороне сервера.
    А для решения проблемы скорости вашего кода вам следует провести его диагностику, найти узкие места и устранить их.
    Ответ написан
  • Как сделать мультиплатформенный проект c# используя Visual Studio?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    Просто создаёте кроссплатформенный .Net 9 проект и добавляете профили публикации для разных ОС. Далее под виндой делаете сборку для винды, а под линуксом соответственно делаете сборку для линукса с использованием этих самых профилей. Если вам нужна графическая оболочка - то отличным выбором будет что-то типа Avalonia. Для платформенно-зависимого кода используйте стандартные директивы препроцессора. Если вы хотите для разных платформ использовать разные фреймворки/библиотеки, есть много кода для разных платформ или сложные зависимости, то в этом случае удобнее сделать три проекта: по отдельному проекту для каждой платформы и третий зависимый проект в виде библиотеки с общим для всех платформ кодом.
    Ответ написан
  • Как работают переводы на другие языки в играх?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    перевод игры лежит в отдельном файле(например json и хранит в себе каждую строчку текста, которая применяется в игре), и потом в коде запрашивать нужную строку из файла и брать от туда значение текста для последующего применения на сцене

    Да, так оно и работает.

    или есть способы попроще

    Проще уже некуда.
    Ответ написан
    4 комментария
  • Как реализовать массив хранящий различные типы данных?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    Именно массив с любыми типами вот так можно сделать:
    object[] foo = { "Abc", 123 };
    А на картинке у вас уже массив объектов со своими свойствами (в соседнем ответе пример привели уже).
    Ответ написан
  • В чем смысл public _ {get;set} в c#?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    Есть поля и есть свойства. Доступ к свойству осуществляется через методы - получения, записи, добавления или вычитания свойства. У полей нет отдельных методов доступа - используется только стандартный механизм доступа. RTFM:
    classes and structs -> fields
    classes and structs -> properties
    Ответ написан
    Комментировать
  • Почему такая ошибка в скрипте и как её исправить?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    Там же написано, что это метод, а не свойство или поле. Да и из названия это вполне очевидно. А ещё есть и всплывающая подсказка, в которой тоже будет написано.
    Ответ написан