• Поля и Свойства/get/set - что это? Как понять? Можно ли объяснить как то по проще/человечески?

    WNeZRoS
    @WNeZRoS
    Как я понимаю, поля и методы вам уже понятны.

    Например, есть у вас код который выводит в консоль площадь квадрата:
    void Calculate()
    {
        var quad = new Quad();
        quad.Size = 10;
        Console.WriteLine(quad.Area);
    }

    А сам класс квадрата определён так:
    class Quad
    {
        public float Size;
        public float Area;
    }

    Как видно, площадь (Area) никто не вычисляет и выводится всегда будет 0, т.е. код не работает.
    Чтобы его починить нужно что-бы кто-то эту площадь.

    (1) Самый тупой вариант, посчитать её в Calculate
    void Calculate()
    {
        var quad = new Quad();
        quad.Size = 10;
        quad.Area = quad.Size * quad.Size;
        Console.WriteLine(quad.Area);
    }

    В этом варианте нам надо править код, который использует этот класс Quad. Если этого кода много, то это куча лишней работы. И в целом, класс Quad теряет смысл, все его переменные можно в методах объявить, это будет намного оптимальнее.
    (2) Вариант чуть лучше - сделать метод расчёта площади в Quad
    class Quad
    {
        public float Size;
        public float Area;
    
        public void UpdateArea()
        {
            Area = Size * Size;
        }
    }

    Нам всё-равно нужно менять код использующий этот класс Quad, и добавлять вызов UpdateArea после изменения размера. Тоже не очень-то удобно.


    Если Area надо всегда считать, то может лучше сделать метод?
    class Quad
    {
        public float Size;
    
        public float GetArea()
        {
            return Size * Size;
        }
    }

    Теперь не нужно вызывать ничего лишнего, но нам придётся пройтись по всем старым использования поля Area и заменить их на вызов нового метода GetArea.

    Но можно сделать метод GetArea похожим на поле Area и не придётся менять код его использующий. Для этого и применяются Свойства.
    class Quad
    {
        public float Size;
    
        public float Area
        {
            get { return Size * Size; }
        }
    }

    При использовании класса Quad теперь Area выглядит как поле, но его нельзя менять т.к. у него нет set части.

    Можно пойти другим путём, и пересчитывать поля Area при изменении размера:
    class Quad
    {
        private float size;
    
        public float Size
        {
            get { return size; }
            set
            {
                size = value;
                Area = size * size;
            }
        }
    
        public float Area;
    }

    В таком варианте у нас Area считается при изменении Size, а не при доступе к Area. Какой вариант лучше - зависит от задачи и её требований.

    Если подытожить, то Свойства это методы похожие по использованию на поля.
    аццессор = accessor = средство доступа - обобщённое название для get и set
    Ответ написан
    Комментировать
  • Как определить что комп воспроизводит видео или графику на экран?

    WNeZRoS
    @WNeZRoS
    Когда какое-то приложение хочет остановить засыпание компьютера оно оставляет системе запрос через функцию PowerCreateRequest.
    Получить эти запросы через публичный API похоже не возможно, т.к. этого API нет.
    Но есть консольная утилита powercfg, если её запустить с ключом -REQUESTS она выдаёт список активных запросов. Для её работы нужны права администратора. Парсить её вывод сложно из-за локализованных строк, но для утилиты для себя это не проблема.

    Когда запущено видео в хроме она вывела мне это:
    DISPLAY:
    [PROCESS] \Device\HarddiskVolume2\Program Files (x86)\Google\Chrome\Application\chrome.exe
    Playing video
    
    SYSTEM:
    [DRIVER] Realtek High Definition Audio (HDAUDIO\FUNC_01&VEN_10EC&DEV_0887&SUBSYS_1458A002&REV_1003\4&3828eb94&0&0201)
    Аудиопоток уже используется.
    [PROCESS] \Device\HarddiskVolume2\Program Files (x86)\Google\Chrome\Application\chrome.exe
    Playing audio
    
    AWAYMODE:
    Нет.


    Из C# этот текст можно получить так:
    var processStartInfo = new ProcessStartInfo("powercfg.exe", "-REQUESTS")
    {
        UseShellExecute = false,
        RedirectStandardOutput = true
    };
    
    var process = Process.Start(processStartInfo);
    var data = process.StandardOutput.ReadToEnd();
    Ответ написан
  • Где задается настройка, чтобы юнит-тесты, запущенные через Resharper, вываливали исключения непосредственно на строке возникновения?

    WNeZRoS
    @WNeZRoS
    Нужно включить в окне Debug > Windows > Exception Settings нужные Common Language Runtime Exceptions.
    Всё выбранное в этом окне будет попадать в дебаггер до того как их обработает программа. Поэтому могут приходить не фатальные исключения которые позже где-то поймаются и обработаются.
    Ответ написан
    Комментировать
  • Как исправить ошибку при перегрузке методов C#?

    WNeZRoS
    @WNeZRoS
    Проблема в том что вы определили две локальные функции в функции, что делать нельзя.
    Перенесите определение из блока функции в класс, и всё будет работать как в примерах из интернета.
    Ответ написан
    Комментировать
  • Как изменить фон у button по Click при реализованном новом шаблоне?

    WNeZRoS
    @WNeZRoS
    Чтобы button.Background = Brushes.Red; работал нужно в ControlTemplate для Border'a вместо фиксированного цвета/градиента использовать биндинг на фон кнопки:
    {TemplateBinding Background}

    Но при этом в IsPressed триггере всё ещё останется фиксированный цвет, чтобы его тоже можно было менять нужно найти или создать (attached) DependencyProperty у кнопки куда этот цвет можно забиндить.
    Так же в триггерах не работает TemplateBinding, вместо него следует использовать такой биндинг:
    {Binding RelativeSource={RelativeSource TemplatedParent}, Path=PressedBackground}
    Ответ написан
    1 комментарий
  • Как запретить редактору вызывать "readonly static" во время редактирования?

    WNeZRoS
    @WNeZRoS
    Запретить нельзя.
    Простой вариант - добавить в метод Localize заглушку:
    #if UNITY_EDITOR // Кода внутри этого #if не будет в собранной версии игры
    if (isLocalizationInitialized == false)
        return localicationKey;
    #endif
    Ответ написан
    Комментировать
  • Что делает в данном случае метод Count?

    WNeZRoS
    @WNeZRoS
    Делает он тоже самое что и следующих код:
    int vowels_count = 0;
    foreach(var x in line)
    {
        if (vowels.Contains(x))
            vowels_count++;
    }
    Ответ написан
  • Какие нюансы есть при создании low poly моделей (персонажей) для игровых движков?

    WNeZRoS
    @WNeZRoS
    Треугольники можно использовать в любом случае, просто зачастую они доставляют неудобств при моделлировании.
    Триангуляция - разделение многоульников на треугольники, когда уже есть готовый треугольник он не трогается.
    Бывает нужно трианглуровать вручную чтобы треугольники точно образовались как ожидается.
    Ответ написан
    Комментировать
  • Сокращение больших чисел в Unity3D. Как это сделать?

    WNeZRoS
    @WNeZRoS
    static string[] names = { "", "K", "M", "B", "T" };
    	
    static string FormatMoney(decimal digit)
    {
    	int n = 0;
    	while (n + 1 < names.Length && digit >= 100m)
    	{
    		digit /= 1000m;
    		n++;
    	}
    	return string.Format("{0}{1}", digit, names[n]);
    }


    Засчёт digit >= 100m могут получиться числа типа 0.11K или 0.25M.
    Если дробные числа нужны только больше 1, то сравнение нужно сделать с 1000.
    Ответ написан
    2 комментария
  • C# WPF программное создание кнопки?

    WNeZRoS
    @WNeZRoS
    У GroupBox в WPF нет Children, но есть Content. В Content нужно положить какую-то панель, а уже потом в эту панель (у неё есть Children) можно добавлять элементы.

    <GroupBox Header="" HorizontalAlignment="Left" Height="100" Margin="10,67,0,0" VerticalAlignment="Top" Width="772">
        <StackPanel Name="ConfigsBox" />
    </GroupBox>
    Ответ написан
    Комментировать
  • Как отрисовать много элементов в ItemsControl?

    WNeZRoS
    @WNeZRoS
    Лаг может возникать из-за нескольких причин.
    Первая причниа - долгая загрузка или создание элементов. Тогда, как пишет Михаил Усоцкий, следует вынести загрузку в другой поток.

    Вторая причина - долгая отрисовка в WPF. В данном случае поможет виртуализация. Если у вас используется ItemsControl, то стоит его заменить на ListBox - в ItemsControl не работает виртуализация.
    <ListBox VirtualizingStackPanel.IsVirtualizing="True" ItemsSource="{Binding ...}" />

    Если у вас используется нестандартный ItemsPanel, то нужно также использовать панель с поддержкой виртуализации. В стандартном WPF такая одна - VirtualizingStackPanel, аналог StackPanel. Какие-то другие придётся писать самому или искать уже кем-то написанные.
    Ответ написан
  • Почему SelectedItem у ListView срабатывает только 1 раз, а SelectedIndex - всегда?

    WNeZRoS
    @WNeZRoS
    А что у вас в Items?
    Я такое поведение видел только когда в Items одинаковые элементы (ReferenceEquals(a, b) == true)
    Ответ написан
  • WPF: Как в ToolTip загнать результат статического метода, в который передается значение из модели?

    WNeZRoS
    @WNeZRoS
    Совсем без кода не получится. Нужно сделать IMultiValueConverter, куда биндить строку и число. В самом конвертере вызывать этот статичный метод. При этом TextBlock что возвращается должен быть новым (нигде до этого не использованным), а то будут краши.
    Ответ написан
    Комментировать
  • Почему крашится игра (и редактор) при показе/скрытии курсора?

    WNeZRoS
    @WNeZRoS
    Если краш происодит и с однострочным кодом
    GameController->bMouseShowCursor = false;
    то проблема явно в том что GameController не инициализирован или указывает на уже освобождённую память.
    Ответ написан
  • Можно ли запечь несколько UV карт?

    WNeZRoS
    @WNeZRoS
    Судя по ошибке вы запекаете в Blender используя Blender Render.
    У него с запеканиями есть одна не очевидность. Запекания производятся на текстуру, выбранную в режиме редактирования.
    Т.е. надо на целевом обьекте перейти в режим редактирования геометрии, выделить всё, и находясь в этом режиме в окне UV/Image Editor выбрать текстуру в которую будет производится запекание.
    Ответ написан
    3 комментария
  • Как добавить в ListBox кнопку в начало или конец списка?

    WNeZRoS
    @WNeZRoS
    При бидинге коллекции к ItemsControl создаётся CollectionView (для IEnumerable, для IList - ListCollectionView), который может дополнительно отсортировать или отфильтровать коллекцию. Элементы, видимые на экране, берутся из этого CollectionView, а не из оригинальной коллекции.

    ListCollectionView имеет проперти NewItemPlaceholderPosition, с помощью которого можно добавить фейковый элемент в начало или конец.
    // CollectionView можно получить двумя способами:
    // 1. Просто получить дефолтный вариант для коллекции
    var collectionView = (ListCollectionView)CollectionViewSource.GetDefaultView(Items);
    // 2. Создать свой, тогда именно этот созданный collectionView надо передавать для биндинга в ItemsSource.
    var collectionView = new ListCollectionView(Models);
    
    // После, можно добавить фейковый элемент
    collectionView.NewItemPlaceholderPosition = NewItemPlaceholderPosition.AtBeginning;

    После этого в ListBox появится элемент CollectionView.NewItemPlaceholder, который можно отдельно стилизовать с помощью DataTemplateSelector.

    DataTemplateSelector
    public sealed class NewItemTemplateSelector : DataTemplateSelector
    {
       public DataTemplate ItemTemplate { get; set; }
       public DataTemplate NewItemPlaceholderTemplate { get; set; }
    
       public override DataTemplate SelectTemplate(object item, DependencyObject container)
       {
          if (item == CollectionView.NewItemPlaceholder)
             return NewItemPlaceholderTemplate;
    
          return ItemTemplate;
       }
    }

    <ListBox.ItemTemplateSelector>
        <t:NewItemTemplateSelector>
            <t:NewItemTemplateSelector.ItemTemplate>
                <DataTemplate>
                    <!-- Шаблон обычного элемента -->
                </DataTemplate>
            </t:NewItemTemplateSelector.ItemTemplate>
            <t:NewItemTemplateSelector.NewItemPlaceholderTemplate>
                <DataTemplate>
                    <!-- Шаблон CollectionView.NewItemPlaceholder -->
                    <Button Content="+" />
                </DataTemplate>
            </t:NewItemTemplateSelector.NewItemPlaceholderTemplate>
        </t:NewItemTemplateSelector>
    </ListBox.ItemTemplateSelector>

    Ответ написан
    Комментировать
  • Как сделать бота Telegram без BotFather'a?

    WNeZRoS
    @WNeZRoS
    Для этого надо вместо bot api использовать обычный клиент. Например, клиенты на python:
    https://github.com/pyrogram/pyrogram
    https://github.com/LonamiWebs/Telethon
    Ответ написан
    Комментировать
  • Почему GD2 не отрисовывает русские символы на сервере apache?

    WNeZRoS
    @WNeZRoS
    Ломается картинка скорее всего из-за ошибок, которые отправляются вместо или вместе с картинкой.
    Вероятно шрифт не нашёлся или сам GD2.
    Ответ написан
  • Как добавить элемент в массив когда цикл с этим массивом запущен?

    WNeZRoS
    @WNeZRoS
    Ваш код:
    List<BlueprintLink> blueprintLinks = new List<BlueprintLink>();
    BlueprintLink parentBlueprintLink = db.BlueprintLinks.FirstOrDefault(m=>m.BlueprintId == helper.BlueprintId && m.ProductId == product.Id);
    blueprintLinks.Add(parentBlueprintLink);
    foreach (var blLink in blueprintLinks.ToArray()) // .ToArray() создаёт копию blueprintLinks, в котором будет один добавленный элемент на предыдущей строчке
    {
        List<BlueprintLink> _blueprintLinks = db.BlueprintLinks.Where(m=>m.ParentId == blLink.BlueprintId && m.ProductId == blLink.ProductId).ToList();
        blueprintLinks.AddRange(_blueprintLinks); // добавляем новые элементы в оригинальный список
    } // выходим из цикла потому что в копии сделанной ToArray всего один элемент


    Правильный вариант:
    var blueprintLinks = new List<BlueprintLink>();
    blueprintLinks.Add(db.BlueprintLinks.First(m => m.BlueprintId == helper.BlueprintId && m.ProductId == product.Id));
    for(int i = 0; i < blueprintLinks.Count; i++) // Идём по оригинальному списку от 0 до конца
    {
        blueprintLinks.AddRange(db.BlueprintLinks.Where(m => m.ParentId == blLink.BlueprintId && m.ProductId == blLink.ProductId)); // добавляем новые элементы в список
    } // blueprintLinks.Count увеличился на кол-во добавленных элементов и есть куда идти дальше
    Ответ написан
    Комментировать
  • Как получить координаты курсора мыши c несколькими мониторами?

    WNeZRoS
    @WNeZRoS
    У главного экрана координаты левого верхнего угла - (0, 0).
    Когда главный экран не самый верхний и левый, то появляются отрицательные координаты.
    Чтобы перевести экранные координаты в координаты картинки нужно отнять desktopRect.Left и desktopRect.Top
    Ответ написан
    1 комментарий