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

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    Если вам именно самого окна в нормальных координатах, то можно использовать WinApi:
    https://github.com/VoidVolker/LockScreen/blob/mast...
    public static class Native
    {
        [DllImport("user32.dll")]
        private static extern bool GetWindowRect(IntPtr hwnd, ref RECT rectangle);
    
        [DllImport("user32.dll")]
        private static extern bool GetClientRect(IntPtr hwnd, ref RECT rectangle);
    
        public RECT GetWindowPos(IntPtr hwnd)
        {
            var r = new RECT();
            GetWindowRect(hwnd, ref r);
            return r;
        }
    
        public RECT GetClientPos(IntPtr hwnd)
        {
            var r = new RECT();
            GetClientRect(hwnd, ref r);
            return r;
        }
    
        [Serializable]
        [StructLayout(LayoutKind.Sequential)]
        public struct RECT(int left, int top, int right, int bottom)
        {
            public int Left = left;
            public int Top = top;
            public int Right = right;
            public int Bottom = bottom;
            public readonly int Width => Right - Left;
            public readonly int Height => Bottom - Top;
        }
    }

    Значения RenderSize и ActualWidth/ActualHeight будут после вычисления положения самого элемента. Скорее всего вы слишком рано пытаетесь получить к ним доступ. Запустите ваше приложение и в отладчике посмотрите в дереве окон значения.
    Плюс учтите, что в WPF свои пиксели, которые надо конвертировать в нормальные и обратно с учётом DPI текущего монитора, на котором располагается окно (на SO есть готовый код). И из-за этого WPF окно невозможно 100% точно позиционировать в нужных координатах и нужного размера в многомониторной конфигурации.

    Пример работы с визуалом элемента при его инициализации:
    public class MyControl : Control
    {
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            // Размеры и позиция элемента вычислены и он готов к работе
        }
    }

    https://github.com/VoidVolker/LockScreen/blob/mast... - пример из реального проекта.
    Т.е., наследуете свой элемент от базового класса или любого другого элемента и вклиниваетесь в событие применения шаблона элемента. В разметке XAML добавляете ссылку на класс и спокойно используете свой элемент как обычно.
    Ответ написан
    Комментировать
  • Можно ли получить значение свойства, прототип которого помечен в интерфейсе атрибутом?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    using System.Reflection;
    
    namespace ConsoleAppTest
    {
        public static class Program
        {
            private static void Main(string[] args)
            {
                Test obj = new() { Prop1 = "Prop1 Value" };
                // Получаем тип объекта
                Type objType = typeof(Test);
                // Получаем список интерфейсов
                Type[] interfaces = objType.GetInterfaces();
                foreach (Type iface in interfaces)
                {
                    // Получаем список свойств интерфейса
                    PropertyInfo[] ifaceProperties = iface.GetProperties();
                    foreach (PropertyInfo prop in ifaceProperties)
                    {
                        // Ищем нужный аттрибут в свойстве
                        Attribute? attribute = prop.GetCustomAttribute<TestAttribute>();
                        if (attribute != null)
                        {
                            // Получаем значение свойства
                            object? propValue = prop.GetValue(obj); // -> Prop1 Value
                        }
                    }
                }
            }
        }
        
        [AttributeUsage(AttributeTargets.Property)]
        public sealed class TestAttribute : Attribute
        { }
    
        internal sealed class Test : ITest
        {
            public string Prop1 { get; set; } = string.Empty;
        }
    
        internal interface ITest
        {
            [Test]
            public string Prop1 { get; set; }
        }
    }
    Ответ написан
  • Как реализовать на C# интерфейс программы не просто кнопки на wpf или winForms?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    WPF/MAUI позволяет рисовать любые интерфейсы с любыми эффектами. Да, можно кинуть элемент на форму, но возможности формошлёпа ограничены, поэтому обычно пишут кодом, а формошлёпы полезны для прототипов и нубов. В WPF/MAUI стандарт - MVVM паттерн и плюс ещё несколько других вариантов есть. На хабре поищите статьи про него и библиотеку Prism (рекомендую) - там есть очень хорошие и подробные статьи. Интерфейс описывается с помощью XML, а именно - XAML. Да, оно не идеально, для маленьких проектов не очень практично, хоть и вполне применимо. А вот в средних и больших/сложных проектах - отличное решение, особенно в команде.

    WinForms сегодня имеет смысл использовать только если вам нужна поддержка специфических функций, Windows XP или просто хотите по-быстрому наформошлёпить что-то маленькое и одноразовое. В остальном признано устаревшей технологией и применяется только как дополнение или костыль для исправления костылей WPF. Да, в WPF тоже есть костыли и они очень хорошо чувствуются и с которыми приходится бороться (например невозможность абсолютно точного позиционирования WPF окна на мультимониторной конфигурации из-за костылей в механизмах DPI винды и WPF).

    Ну и плюс отдельного упоминания заслуживают альтернативные UI библиотеки и фреймворки типа Avalonia, Uno и иже с ними.

    Вот вам несколько реальных примеров реализации дизайнерских интерфейсов:
    WPF custom GUI
    900181ba79.png
    2791f5a63c.png
    71ab1f8462.png

    Вот тут можно посмотреть исходный код небольшого проекта с использованием паттерна MVVM: https://github.com/VoidVolker/LockScreen (тут уже интерфейс максимально простой). Несмотря на то, что само приложение на WPF, окно с картинкой пришлось делать на WinForms из-за костыльного DPI в современных виндах и, особенно в WPF. Аналогично пришлось поступать и в приложении со встроенным RDP клиентом - там всё ещё веселее в виде взаимного встраивания WPF и WinForms друг в друга и разделения на несколько проектов для создания работающих зависимостей от системных библиотек - спасибо LibMSTSC и мелкомягким за очень весёлые приключения.
    Ответ написан
  • Почему курсор мышки перестал совпадать с позицией на экране?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    Переключите масштабирование экрана в 100% и проверьте код - всё должно работать как было. В WPF накрутили свои фичи вокруг масштабирования и теперь даже банальное размещение окна в нужной позиции и нужного размера - это цирк с конями на велосипедах, жонглирующими хомяками-акробатами. К сожалению под рукой нет кода, но он легко гуглится по ключевым словам типа WPF DPI real cursor position / real window position. Там надо для каждого экрана получать DPI и использовать его для получения WPF координат или реальных координат на экране.
    Ответ написан
    2 комментария
  • Как реализовать просмотр изображения?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    Изображение состоит из пикселей. Берёте эти пиксели и делаете с ним всё что угодно: копируете в новое изображение, удаляете, меняете, добавляете и т.д. и т.п. Вы же ведь уже смогли прочитать файл изображения в память? Ну вот и остальное аналогично. Есть даже готовые библиотеки. Например:
    Ответ написан
  • Opengl server rendering c#?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    Проще всего взять что-то готовое для ренедеринга, чем писать с нуля. Например блендер: headless blender renderserver with CrowdRender, 3 Steps to Call Blender from the CLI.
    Ответ написан
  • Как научить ИИ прыгать по платформам за игроком?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    Точно так же как и любой другой алгоритм:
    1. Берёте бумажку, ручку и описываете задачу кратко и в общем
    2. Делаете декомпозицию задачи, разбив её на несколько меньших подзадач
    3. Повторяете декомпозицию вниз до самых простых и понятных действий
    4. Рисуете логическую схему со всеми деталями и действиями
    5. Пишете код
    6. Profit!

    Пример

    5bd748db6d572869658821.png
    Ответ написан
    Комментировать
  • Как частично наследовать в Unity метод update, start и т.д.?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    ООП -> Наследование
    public class Foo
    {
        public virtual void Update() 
        {
            Console.WriteLine("Foo->Update()");
        }
    }
    
    public class Bar : Foo
    { 
        public override void Update()
        {
            base.Update();                
            Console.WriteLine("Bar->Update()");
        }
    }
    Ответ написан
    Комментировать
  • Как создать свой pet project?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    Точно так же как и любой другой:
    1. Формулируете вашу задачу в виде какого-то текстового/графического описания
    2. Формулируете ТЗ с конкретными требованиями, ограничениями и всем прочим
    3. На основе ТЗ разрабатываете ЧТЗ (Частное ТЗ) со всеми полными деталями, описаниями всех действий, событий, взаимодействий и прочее
    4. Используя ЧТЗ подготавливаете проект - архитектура, инструменты, системы, подсистемы и прочее с полным описанием, декомпозированными элементами вниз до самых простых и прочее
    5. Берёте проект и по шагам его реализовываете
    6. Profit
    Ответ написан
    Комментировать
  • Какие фреймворки надо учить для Unity c#?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    Ответ будет тот же, что и для любой другой области в разработке ПО: Какой CMS движок учить начинающему?
    Ответ написан
  • Графики в Visual Studio 2022?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    В WPF спокойно можно использовать компоненты из WinForms. Если знаете и давно используете их - то это самый простой вариант в вашем случае будет.
    Или вот еще пара примеров:
    Ответ написан
    5 комментариев
  • Какой тип события использовать для немедленного действия для элемента, по которому произведён клик в ListView элементе?

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

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    RTFM: System.Windows.Controls -> ListView
    • Свойство SelectedItem
    • Событие SelectionChanged

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

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    Именно так нельзя. Но можно вот так, если очень надо: Есть ли способ преобразовать объект к типу?
    В вашем же случае, если тип аргумента неизвестен, следует хранить аргумент в типе object и отдельно его тип. Либо реализовать поддержку типов всех возможных аргументов. А если еще подумать, то можно заменить большую часть вот этого кода обычным словарём.
    Ответ написан
  • Есть ли способ преобразовать объект к типу?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
  • Ошибки в программе на .Net?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    Можно дизассемблировать, провести дебаг и пересобрать. Если приложение обфусцировано - то это займет больше времени и будет сложнее. Судя по логу - там ошибка в параметрах конструктора при создании изображения. Предполагаю, что ошибка у вас воспроизводится при каких-то определённых параметрах задаваемых в приложении.
    Код конструктора, в котором происходит ошибка (примерно, ибо там может быть код другой версии, а искать сейчас конкретную версию нет особого смысла):
            /// 
            ///  
            ///    
            ///       Initializes a new instance of the Bitmap class with the specified 
            ///       size and format.
            ///    
            /// 
            public Bitmap(int width, int height, PixelFormat format) { 
                IntPtr bitmap = IntPtr.Zero;
     
                int status = SafeNativeMethods.Gdip.GdipCreateBitmapFromScan0(width, height, 0, (int) format, NativeMethods.NullHandleRef, out bitmap); 
    
                if (status != SafeNativeMethods.Gdip.Ok) 
                    throw SafeNativeMethods.Gdip.StatusException(status);
    
                SetNativeImage(bitmap);
            } 
    
            ///  
            ///  
            ///    Initializes a new instance of the
            ///  
            /// class with the specified size.
            /// 
            public Bitmap(int width, int height) : this(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb) {
            }

    www.dotnetframework.org/default.aspx/DotNET/DotNET...
    Ответ написан
    6 комментариев
  • Возможно ли решить по другому вывод информации?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    Сделать декомпозицию и рефакторинг вашего алгоритма:
    1. Берёте бумажку, ручку и рисуете весь алгоритм
    2. Разбиваете алгоритм на более простые элементы и так до самого простого элемента
    3. Переработать логику алгоритма для его упрощения, скомпоновав одинаковые части в блоки (функции), классы, модули, убрав не нужное, упростив там, где возможно и т.д. и т.п.
    4. Реализовать получившийся алгоритм в виде кода

    Например, вместо констант в коде использовать данные сразу из таблицы, вместо проверки каждой минуты сделать цикл и т.д. и т.п.
    Ответ написан
    Комментировать
  • Как обработать данные(файл с данными на 14гб)?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    Либо увеличить объем памяти машины, на которой производите расчёты либо оптимизировать ваши алгоритмы по потребляемой памяти.
    Ответ написан
    4 комментария
  • Как в C# работать с json?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    dynamic же есть:
    https://www.newtonsoft.com/json/help/html/QueryJso...
    https://www.newtonsoft.com/json/help/html/CreateJs...
    string json = @"[
      {
        'Title': 'Json.NET is awesome!',
        'Author': {
          'Name': 'James Newton-King',
          'Twitter': '@JamesNK',
          'Picture': '/jamesnk.png'
        },
        'Date': '2013-01-23T19:30:00',
        'BodyHtml': '&lt;h3&gt;Title!&lt;/h3&gt;\r\n&lt;p&gt;Content!&lt;/p&gt;'
      }
    ]";
    
    dynamic blogPosts = JArray.Parse(json);
    
    dynamic blogPost = blogPosts[0];
    
    string title = blogPost.Title;
    
    Console.WriteLine(title);
    // Json.NET is awesome!
    
    string author = blogPost.Author.Name;
    
    Console.WriteLine(author);
    // James Newton-King
    
    DateTime postDate = blogPost.Date;
    
    Console.WriteLine(postDate);
    // 23/01/2013 7:30:00 p.m.

    dynamic product = new JObject();
    product.ProductName = "Elbow Grease";
    product.Enabled = true;
    product.Price = 4.90m;
    product.StockCount = 9000;
    product.StockValue = 44100;
    product.Tags = new JArray("Real", "OnSale");
    
    Console.WriteLine(product.ToString());
    // {
    //   "ProductName": "Elbow Grease",
    //   "Enabled": true,
    //   "Price": 4.90,
    //   "StockCount": 9000,
    //   "StockValue": 44100,
    //   "Tags": [
    //     "Real",
    //     "OnSale"
    //   ]
    // }
    Ответ написан
    3 комментария
  • Как тип переменной передать в аргумент типа?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    В общем случае примерно так:
    public class BarType
    { }
    
    public class Foo
    {
        public static string Bar<T>() => $"Bar() is called with generic: {typeof(T).FullName}";
    }


    Type type = typeof(Foo);
    MethodInfo mi = type.GetMethods().Single(m => m.Name == "Bar" && m.IsGenericMethodDefinition);
    MethodInfo genericMi = mi.MakeGenericMethod(typeof(BarType));
    object result = genericMi.Invoke(null, []);
    Console.WriteLine($"Result: {result}");
    
    >> Result: Bar() is called with generic: Example.App+BarType
    Ответ написан
    Комментировать