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

    @Sumor
    Для этого у события нужно описать методы add и remove:
    using System;
    
    namespace AddRemoveTest
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                var a = new A();
                a.MyEvent += (s,e) => {Console.WriteLine("Event");};
                
                
                a.MyEvent -= (s,e) => {Console.WriteLine("Event");};
            }
        }
        
        public class A
        {
            public event EventHandler MyEvent
            {
                add{
                    
                    Console.WriteLine("Add event");
                }
                remove{
                    Console.WriteLine("Remove event");
                }
            }
        }
    }
    // Вывод:
    // Add event
    // Remove event
    Ответ написан
    Комментировать
  • Нужен ли INotifyCollectionChanged для коллекций если я его не использую?

    @Sumor
    Если хотите что-то проверить - создайте простой тестовый проект и посмотрите.

    Если у вас объекты реализуют INotifyPropertyChanged, то даже если они были привязаны к ItemsControl с помощью IEnumerable, привязанные (Binding) свойства в шаблоне обновятся. Они не пересоздадутся целиком, а именно обновятся те свойства, которые зависят от изменённых свойств вашего объекта. Например
    <ItemsControl>
      <ItemsControl.ItemTemplate>
        <DataTemplate>
             <TextBlock Text="{Binding Text}" Foreground="{Binding ForeColor}" />
        </DataTemplate>
      </ItemsControl.ItemTemplate>
    </ItemsControl>

    При изменении свойства Text вашего объекта обновится текст элемента. При изменении цвета - обновится цвет.

    Но если вы в ItemsSource кладёте IEnumerable, то изменения собственно коллекции не отслеживаются. ни добавление, ни удаление. Если у вас изменилась коллекция вам нужно переприсваивать её заново и тогда будут заново созданы все визуальные элементы.
    Для отслеживания изменения коллекции она должна реализовывать INotifyCollectionChanged. Вы можете за основу взять коллекции ObservableCollection<> - они уже реализуют необходимые события.
    Соответственно, если в NotifyCollectionChanged будет указано, что добавился элемент - только он и отрисуется. Если элемент удалён - он и будет удалён. Остальные элементы не будут затронуты.
    Ответ написан
    1 комментарий
  • Почему нельзя использовать varchar для цифр?

    @Sumor
    Когда компьютеры были большими...
    В общем для записи больших чисел цифрами, с возможностью работать с каждым разрядом был придуман тип packed decimal или binary-coded decimal. Его поддержка до сих пор есть в современных процессорах. Смысл в том, что в каждых 4-х битах числа хранится цифра 0-9, значения A-F не используются. Выигрыш в хранении, по сравнению с varchar - в 2 раза.
    Можно развить эту тему и хранить цифры в массиве Int32, используя числа от 0-999999999 по 9 разрядов в каждом элементе. Для перевода в строку достаточно каждое число перевести в строку и соединить.
    Ответ написан
    Комментировать
  • Как убрать ошибку при работе с Excel с помощью C#?

    @Sumor
    Добавьте в ссылки проекта ссылку на Microsoft Visual Basic for Applications Extensibility 5.3 library
    А также нужна не ссылка на Excel.exe, а там же в ссылках (references) проекта добавить ссылку на Microsoft.Office.Interop.Excel
    Ответ написан
  • Как удалить дубликаты (string) с помощью C#?

    @Sumor
    var str = "Толщина: 9 см<br><br>Длина: 160 см<br>Ширина: 70 см<br>Детские:Да<br><br>Детские:Да<br><br>Детские:Да<br><br>Детские:Да<br>";
    
    foreach(var s in str.Split(new string[] {"<br>"}, StringSplitOptions.RemoveEmptyEntries).Distinct())            
        Console.WriteLine(s);
    Ответ написан
  • Как определить из каких букв состоит слово?

    @Sumor
    Если алфавит ограничен русскими буквами в одном регистре, без буквы ё, то можно предложить более быстрый и хитрый подсчёт, основанный на том, что в типе int - 32 бита и сопоставить каждой найденной букве свой бит.
    Тогда достаточно быстро определяются буквы, участвующие в слове. (В коде 'А' - большая русская А).
    // Подсчёт
    var str = "ТОСТЕР";
    var result = 0;
    foreach(var ch in str)
    {
        result |= (1 << ((int)ch - (int)'А'));
    }
    
    // Вывод результата
    for(var i = 0; i < 32; i++)
    {
        if((result & (1 << i)) == (1 << i))
            Console.WriteLine((char) ((int)'А' + i));
    }
    // Вывод:
    // Е
    // О
    // Р
    // С
    // Т

    Код можно переложить на латинские буквы, а также с небольшими переделками приспособить под алфавиты до 64 букв, используя Int64.
    Ответ написан
    Комментировать
  • Как устранить error CS5001?

    @Sumor
    Добавьте в класс метод
    public static void Main()
    или переделайте программу в dll.
    Ответ написан
    Комментировать
  • ComboBoxMenu_SelectionChanged - стандартная реализация?

    @Sumor
    Вы определитесь у вас ListBox или ComboBox.
    В заголовке ComboBox, поэтому когда вызывается событие, у вас sender типа ComboBox, а не ListBox к которому вы приводите.
    Ответ написан
    Комментировать
  • Как группу CheckBox прибиндить к одному свойcту во ViewModel?

    @Sumor
    Во ViewModel свойство "дни недели" и ссылки для каждого дня недели для добавления и удаления в список:
    private List<System.DayOfWeek> _dayWeeks = new List<System.DayOfWeek>();
    public List<System.DayOfWeek> DayWeeks
    {
      get{return _dayWeeks;}
    }
    
    public bool HasMonday
    {
      get{ return _dayWeeks.Any(d => d  == DayOfWeek.Monday);}
      set
      {
        if(value && !HasMonday)
        {
          _dayWeeks.Add(DayOfWeek.Monday);
          OnPropertyChanged("DayWeeks");
          OnPropertyChanged("HasMonday");     
        }
        if(!value && HasMonday)
        {
          _dayWeeks.Remove(DayOfWeek.Monday);
          OnPropertyChanged("DayWeeks");
          OnPropertyChanged("HasMonday");     
        }
      }
    }
    // Дальше аналогично для других дней недели

    Могут быть нюансы с добавлением/удалением из списка от того, что DayOfWeek это enum. Нет возможности сейчас проверить.

    Есть другой вариант. Создать своё представление дней недели по битам байта: Понедельник - 1, Вторник - 2, Среда - 4, Четверг - 8, Пятница - 16, Суббота - 32, Воскресенье - 64
    Тогда свойство DayWeeks должно по get генерить List на основе битов. А свойства HasMonday и т.п. будут взводить/сбрасывать соответствующий бит.
    Ответ написан
  • Как решить проблему с dll?

    @Sumor
    Битность библиотеки должна совпадать.

    Подключение через DllImport. При этом используемые структуры нужно будет переописать в C#, чтобы ими можно было пользоваться.
    С++ типы в описании функции или структуры описываются с атрибутами маршалинга - для автоматического перевода в типы C#. В частности, ты используешь char - это 8-битный символ, в C# используется Unicode - 2 символа. Для автоматического перевода в Unicode нужно указывать параметр Charset.
    using System.Runtime.InteropServices;
    
    [DllImport("myDll.dll", CallingConvention=CallingConvention.StdCall)]
    public static extern int Card();
    
    [DllImport("myDll.dll", CallingConvention=CallingConvention.StdCall, Charset=Charset.Ansi)]
    public static extern int cudaCard(IntPtr mWnd, IntPtr aWnd, string data, string parms, bool show, bool nopause);
    Ответ написан
    Комментировать
  • Как правильно дополнить команду Application.Delete, сохранив её базовое выполнение?

    @Sumor
    Для назначения обработчиков команде нужно указать в разделе CommangBindings контрола, в котором будет вызываться эта команда или в любом из его логических предков, обработчик событий Execute и/или обработчик CanExecute.
    После этого вы привязываете команду к пункту меню, кнопке, через соответствующее свойство Command, либо указываете горячую клавишу или жест мыши через InputBindings.
    Ответ написан
  • Ошибка при открытии wpf формы?

    @Sumor
    Скорее всего у вас в создаваемом объекте Application установлено закрытие приложения при закрытии последней формы.
    У вас первая форма закрывается и в этот момент Application видит, что форм больше нет - закрывает себя. А вы тут же пытаетесь создать и запустить новую форму.
    Установите для Application.Current.ShutdownMode в OnExplicitShutdown
    Ответ написан
    Комментировать
  • Как получать данные из БД каждые 10 секунд (Entity Framework)?

    @Sumor
    Строчка usersGrid.ItemsSource = db.USER.Local.ToBindingList(); говорит о том, что конкретно этот текущий список записей из таблицы опубликовать в DataGrid. При повторном выполнении Load() у вас создаются новые списки, никак не связанные с тем, что находится сейчас в DataGrid. Поэтому обновления не происходит.
    Чтобы понять что изменилось в БД с момента прошлого считывания можно использовать, например, время изменения записи. И каждые 10 (или сколько вы захотите) секунд считывать только изменённые записи.
    Просто так изменённые записи в уже считанный и добавленный в грид список не обновить. Нужно найти среди существующих строчек те, что обновились в соответствии с запросом и изменить их реквизиты. Так как вы используете BindingList, то по идее после изменения записи в списке DataGrid должен обновить запись на экране.
    Схема может быть примерно такая:
    DataGrid на форме привязан (Binding) к один раз созданному списку сообщений типа BindingList<> или ObservableCollection<>. Сообщения, которые хранятся в этом списке должны реализовывать шаблон PropertyChanged. Список первоначально начитывается при старте формы. После создания, заполнения и привязки к DataGrid нельзя удалять/пересоздавать список. Если вам нужно его перечитать целиком - выполняете Clear() и добавляете записи заново. Далее по таймеру считываете изменённые или добавленные записи и пробегаете по вашему списку и их находите и изменяете. Отрабатывает PropertyChanged на сообщениях, отрабатывает изменение списка, отрабатывает обновление DataGrid. Если у вас считывание из базы происходит недолго, то вам достаточно использовать DispatcherTimer. Он выполняется в том же потоке где живёт DataGrid и список сообщений. Если же вас это не устраивает и вы хотите поиграть в потоки, то вам нужно использовать потокобезопасные коллекции и/или устраивать синхронизацию действий. Но это тема другого вопроса.
    Ответ написан
    Комментировать
  • Как оформить запрос в базу данных если нужно базироваться на дате?

    @Sumor
    Число дней в виде строки это конечно прелестно.
    Как минимум нужно знать что за СУБД.
    В SQLServer есть функция DATEADD(datepart , number , date). В MySql - функция DATE_ADD(date,INTERVAL expr type).
    Преобразуете строку с количеством дней в число, затем прибавляете с помощью указанных функций к сегодняшней дате.
    Ответ написан
    Комментировать
  • Как преобразовать string к wstring?

    @Sumor
    В первом варианте converter не создан и не инициализирован. Отсюда исключение.
    Во втором варианте вы тупо подставляете байты от std::string в std::wstring. Так как в UTF-8 английские символы 1 байт, а в UTF-16 два, а в UTF-32 - четыре, а также русские буквы просто так не переводятся - вы получаете иероглифы.
    В третьем варианте, в выходном буфере должно быть на один символ больше - для нуля на конце. Соответственно и sizeInWords должен быть на 1 больше. Если у вас wchar_t 4 символа, то видимо размер sizeInWords должен будет увеличится вдвое (хотя я в этом до конца не уверен).
    Ответ написан
    2 комментария
  • Почему при закрытии программно документа Word в процессах остается висеть WINWORD.EXE?

    @Sumor
    Это потому, что вы закрыли документ, но не закрыли ворд.
    Для закрытия ворда нужно ему дать команду Quit.
    Ответ написан
    1 комментарий
  • Как устранить гонку при использовании именованного канала?

    @Sumor
    Можно организовать одной трубой, но мороки много. Вы должны "захватить" канал для передачи, например, послав специальную команду "начало передачи". При получении вторая сторона переключается в режим чтения и обязуется не посылать сообщения до сигнала "конец передачи". Первая сторона в момент передачи ничего из трубы не читает.
    Таким образом, ому надо что-то передать - захватывает канал и передаёт, а второй его слушается.

    Можно организовать две трубы. Одна только на передачу, вторая только на приём. Если одна сторона только отвечает на вопросы, то это неплохой вариант. Проблема может возникнуть, если вторая сторона может не только отвечать, но и сама что-то передавать. Тогда нужно аккуратно отделить оба случая, что-бы не допустить внутренней гонки за трубу и разделять оба варианта на приёме.

    А можно организовать 4 трубы. Две на посылку команды первой стороной и ответ второй. И ещё две на посылку команд второй стороны и ответ первой.
    Ответ написан
    Комментировать
  • Как узнать уровень в иерархии выбранного элемента в TreeView?

    @Sumor
    Когда вы программируете на WPF подразумевается, что визуальная часть является отражением вашего представления данных. Поэтому уровень иерархии выбранный элемент должен находить не среди элементов TreeViewItem, а среди родителей выбранного элемента в соответствии с моделью представления данных.
    Пример:
    class A
    {
     public string Name{get;set;}
     public A Parent {get;set;}
     public IEnumerable<A> Children
     {
      get
      {
        return AllItemsOfA.Select(a => a.Parent == this);
      }
     }
     public int Level()
     {
      int level = 0;
      var current = Parent;
      while(current != null)
      {
        current = current.Parent;
        level ++;
      }
      return level;
     }
    }

    Добавив коллекцию таких элементов в TreeView вы у выбранного элемента получите нужный вам уровень иерархии.
    Ответ написан
    Комментировать