• Как получить доступ к главному окну из другого класса в WPF?

    petermzg
    @petermzg
    Самый лучший программист
    Application.Current.MainWindow
    Ответ написан
    Комментировать
  • Строго именованная подпись недопустима для данной сборки DevExpress?

    firedragon
    @firedragon
    Не джун-мидл-сеньор, а трус-балбес-бывалый.
    ClickOnce требует подписанные библиотеки, что бы никто не подменил их.
    Так-что удаляйте подпись, и вставляйте свою.
    Не забудьте налить рома попугаю и повязать повязку на правый глаз.
    https://stackoverflow.com/questions/38716653/remov...
    Ответ написан
    Комментировать
  • Как связать конкретную фигуру с выбранным элементом?

    FoggyFinder
    @FoggyFinder
    Пока нет возможности написать пример, но попробую дополнить ответ когда она появится.

    Если количество отображаемых элементов не слишком большое (в пределах 100-1000), то, вероятно, лучшим вариантом будет вынести часть информации в ViewModel (а именно, координаты расположения линий и состояние IsSelected). В вашем примере этот класс назван Model, но я рекомендую его переименовать, в дальнейшем это может сбить с толку.

    Тогда вы привяжите коллекцию к ItemsControl, где панелью будет выступать Canvas.
    Координаты привяжите индивидуально. Реагировать на изменение цвета можно будет или через триггер или через конвертер, но если вариантов всего 2, то проще, на мой взгляд, будет использовать именно триггер.

    При выделении элемента в коллекции сбрасываете состояние IsSelected предыдущего элемента в False и указанному соответственно ставите True.

    Обновлено:

    Появились несколько свободных минут, привожу пример:

    Для начала, для удобства создадим ViewModelBase, чтобы несколько раз не реализовывать интерфейс INPC:

    public abstract class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    
        protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = "")
        {
            if (EqualityComparer<T>.Default.Equals(storage, value))
                return false;
            storage = value;
            this.OnPropertyChanged(propertyName);
            return true;
        }
    }


    Теперь, как я уже писал выше, нам понадобиться отдельная ViewModel для ячейки, элемента списка:

    public class LineVM : ViewModelBase
    {
        private bool isSelected;
        public bool IsSelected
        {
            get { return isSelected; }
            set { SetProperty(ref isSelected, value); }
        }
    
        public LineVM(string name, int x, int y)
        {
            Name = name;
            X = x;
            Y = y;
        }
        public string Name { get; set; }
    
        public int X { get; private set; }
    
        public int Y { get; private set; }
    }


    Здесь нет необходимости в изменении координат во время работы программы, поэтому сеттеры оставим приватными.

    Главная ViewModel :

    public class ItemsVM : ViewModelBase
    {
        private LineVM selectedVM;
    
        public ObservableCollection<LineVM> Models { get; }
        public LineVM SelectedModel
        {
            get { return selectedVM; }
            set
            {
                if (SelectedModel != null)
                    SelectedModel.IsSelected = false;
                value.IsSelected = true;
                SetProperty(ref selectedVM, value);
            }
        }
    
        public ItemsVM()
        {
            Models = new ObservableCollection<LineVM>
            {
                new LineVM ("A", 10, 20 ),
                new LineVM ("B", 10, 40),
                new LineVM ("C", 10, 60),
                new LineVM ("D", 10, 80)
            };
        }
    }


    я не стал заниматься переименовыванием, но лучше, конечно, чтобы свойства отображали реальное назначение.

    Теперь View часть. Привожу только измененный третий столбец:

    <ItemsControl Grid.Column="2" ItemsSource="{Binding Models}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas IsItemsHost="True" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Line
                X1="0"
                X2="100"
                Y1="0"
                Y2="00">
                    <Line.Style>
                        <Style TargetType="Line">
                            <Setter Property="Stroke" Value="Blue" />
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding IsSelected}" Value="True">
                                    <Setter Property="Stroke" Value="Red" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </Line.Style>
                </Line>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
        <ItemsControl.ItemContainerStyle>
            <Style TargetType="ContentPresenter">
                <Setter Property="Canvas.Left" Value="{Binding X}" />
                <Setter Property="Canvas.Top" Value="{Binding Y}" />
            </Style>
        </ItemsControl.ItemContainerStyle>
    </ItemsControl>


    Тут тоже все достаточно просто - триггер реагирует на изменение свойства IsSelected и меняет цвет на красный для текущего элемента.

    И, для наглядности, оставляю гифку:

    5dd6e7e03664e626729135.gif
    Ответ написан
    2 комментария
  • Как упростить переменную в C#?

    mindtester
    @mindtester Куратор тега C#
    http://iczin.su/hexagram_48
    а еще можно сделать расширение
    для приведенного фрагмента что то типа
    public static string b64toASCII(this string s) => Encoding.ASCII.GetString(Convert.FromBase64String(s));

    преобразуем исходный фрагмент
    LocalData + "Тут".b64toASCII(), 
                LocalData + "Все ".b64toASCII(), 
                LocalData + "значения".b64toASCII(), 
                LocalData + "будут".b64toASCII(), 
                LocalData + "совершенные".b64toASCII(), 
                LocalData + "Разные".b64toASCII(),


    ps base64 явно не нужен для литералов набранных в редакторе. они вообще не требуют дополнительной обработки. это похоже на данные получаемые из сети к примеру. если разделение запятой не ошибка, значит формируется массив. и если LocalData постоянное значение для массива, можно еще и LINQ притянуть
    // сначала собираем base64 данные в массив. с большой вероятностью такой код будет проще
    // пока в нем нет обработок.
    // допустим этот массив называется b64data. тогда итоговый массив можно получить одной строкой
    var target = b64data.Select(x => (LocalData + x.b64toASCII())).ToArray();
    // ToArray() можно заменить на ToList() при желании,
    // но если и дальше использовать LINQ, проще так и шпарить IEnumerable<string>
    // в смысле убрать .ToArray() вообще
    Ответ написан
    Комментировать
  • Как упростить переменную в C#?

    FoggyFinder
    @FoggyFinder
    Можно вынести в отдельную функцию:

    string CreateASCIIStr(string value) => Encoding.ASCII.GetString(Convert.FromBase64String(value));


    или, в локальную, с использованием LocalData:

    string CreateASCIIStr(string value) =>
                    LocalData + Encoding.ASCII.GetString(Convert.FromBase64String(value));


    Добавлено:

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

    В данном случае у вас есть многократный последовательный вызов двух методов:

    Convert.FromBase64String и Encoding.ASCII.GetString

    для удобства их совмещаем в один вызов и получаем

    Encoding.ASCII.GetString(Convert.FromBase64String(value))

    Пример:

    string LocalData = "0";
    string CreateASCIIStr(string value) =>
        LocalData + Encoding.ASCII.GetString(Convert.FromBase64String(value));
    
    var data = new[] {
        CreateASCIIStr("Тут"),
        CreateASCIIStr("Все"),
        CreateASCIIStr("значения"),
        CreateASCIIStr("будут"),
        CreateASCIIStr("совершенные"),
        CreateASCIIStr("Разные")
    };


    Здесь возвращается массив, но если ваши совершенно разные значения в действительности являются массивом, то и обрабатывать их лучше как массив ;-)
    Ответ написан
    3 комментария
  • Как работать с разными версиями одного проекта?

    @Andy_U
    Что удивительно, ответа про использование отдельного бранча для нового проекта я не увидел. Общие изменения делать в основной ветке и мержить их в новую. Можно и наоборот, но чуть сложнее. Или просто cherry pick использовать...
    Ответ написан
    1 комментарий
  • Как работать с разными версиями одного проекта?

    petermzg
    @petermzg
    Самый лучший программист
    Создать 3й проект и вынести туда общие файлы. А в первые два проекта эти файлы добавлять линковкой "Add as Link"
    Ответ написан
    4 комментария
  • Можно ли создать управляемый вирус?

    Zoominger
    @Zoominger
    System Integrator
    Да, можно.
    Ответ написан
    Комментировать
  • Как реализовать LazyLoad у TreeView?

    cyber_roach
    @cyber_roach
    UX дизайнер INEDIapps
    Чем пример с MSDN не устроил ?
    https://docs.microsoft.com/ru-ru/dotnet/framework/...

    Есть момент - при наличии некоторых условий виртуализация отключается:
    - если контейнеры элементов добавляются напрямую к элементу управления ItemsControl.
    - если объект ItemsControl содержит контейнеры элементов различных типов.
    - если для прикрепленного свойства VirtualizingStackPanel.IsVirtualizing установлено значение false
    - если для прикрепленного свойства ScrollViewer.CanContentScroll установлено значение false

    Можно еще взять любой пакет контролов где это реализовано (например Telerik)
    Подсмотреть в их исходниках реализацию виртуализации и сделать свою в преферансом и дамами.
    Ответ написан
    Комментировать
  • Как обработать событие в рамках MVVM через Interactions.Triggers у подключенной библиотеки?

    FoggyFinder
    @FoggyFinder
    Написать свой триггер для учета прикрепляемых событий. Как, например, сделано тут:

    https://sergecalderara.wordpress.com/2012/08/23/ho...

    или тут
    Ответ написан
    3 комментария
  • Как восстановить расширение файла?

    fzfx
    @fzfx
    18,5 дм
    переименовать файл.
    если при переименовании не даёт сменить расширение файла - в любой папке в меню "вид" выбрать "параметры" и там во вкладке "вид" снять галку "скрывать расширения", а потом переименовать файл.
    Ответ написан
    Комментировать
  • Как связать свойство Command Parameter у Context Menu со свойством Name у TextBox, к которому это меню привязано?

    FoggyFinder
    @FoggyFinder
    Вы столкнулись с широко известной проблемой привязки в ContextMenu, ToolTip из-за того что эти элементы не являются частью "визуального" дерева (visual tree).

    В таких случаях предлагается два стандартных решениях - использовать PlacementTarget и прокси-объект. Первое тут должно подойти идеально.

    Прежде чем показать код отмечу, что вместо использования свойства Name в качестве ключа TextBox лучше использовать свойство Tag.

    То есть вместо:

    <TextBox Name="Box_110" ...>

    <TextBox Tag="Box_110" ...>

    Это не принципиальное изменение, но в большинстве ответов для подобных случаев вы встретите использование именно свойство Tag.

    С учетом этого привязка для CommandParameter будет выглядеть вот так:

    <Setter Property="CommandParameter" Value="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}" />


    И немного оффтопа:

    В вашем обработчике ContextMenuClick вы используете постоянное смещение равное 10 и код по сути для каждого кейса одинаков. Вы могли бы сократить код, предварительно заменив подсказку в Tag убрав оттуда префикс "Box_" чтобы получилось что-то подобное:

    public void ContextMenuClick(object param)
    {
        if (int.TryParse(Convert.ToString(param), out int v))
        {
            StampDictionary.TextBoxes[v.ToString()].BoxValue = Name;
            StampDictionary.TextBoxes[(v + 10).ToString()].BoxValue = Signature;
        }
    }


    Если все ключи в словаре числовые, то еще проще будет заменит тип ключа на int.
    Ответ написан
    2 комментария
  • Как динамически менять значение TextBox, если Binding идет через Dictionary?

    FoggyFinder
    @FoggyFinder
    Чтобы сообщить представлению (View) об изменении значения конкретного свойства из VM нужно передать его название в виде параметра:

    OnPropertyChanged(nameof(TextBoxes));

    Непосредственно в самих свойствах вы можете увидеть что идет вызов без передачи параметров:

    OnPropertyChanged();

    Дело в том, что в типичной реализации имя свойства извлекается при помощи атрибута CallerMemberName:

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged([CallerMemberName]string prop = "")
    {
    // ...
    }


    Это не обязательно делать в set. У свойства может не быть открытого сеттера или не быть сеттера вообще. Или если свойство зависит от двух других - например, для автоматического отображения суммы значений, которые должен вводить пользователь.

    В вашем случае с TextBoxes вы не используете сеттер - его можно даже совсем убрать.
    Ответ написан
    2 комментария
  • Как выполнить выгрузку информации по классу по определённому правилу?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    1. Документируете код согласно принятым стандартам, типа такого:
      /// <summary>
      /// Class description
      /// </summary>
      public class SomeClass { }

    2. В параметрах проекта на вкладке "Сборка" ставите галочку "XML-файл документации — далее файл документации можно скормить любому приложению/скрипту, понимающему xml.
    3. Далее ставите приложение Doxygen
    4. В doxygen создаете проект документации, указываете xml файл документации и все требуемые настройки и сохраняете проект в файл
    5. Теперь документацию по всему коду в удобном формате (HTML, LaTeX, RTF, Man, XML, DocBook) можно получить просто выполнив команду:
      doxygen.exe doxyproject
    Ответ написан
    4 комментария
  • C#. Какие библиотеки использовать для распознавания текста?

    Я давно делал подобное.

    Из заметок:
    - AForgeNet — библиотеки компьютерного зрения и искусственного интеллекта;
    - Tesseract — программа для распознавания текстов;
    - Fanndotnetwrapper — обертка .NET нейросети FANN;
    - алгоритм поиска связанности CCLA от Omar Gameel Salem. (поиск ближайших соседей, как определять буквы, и отделять их друг от друга).

    Есть уже ML .NET - https://github.com/dotnet/machinelearning-samples

    У вас картинка идеальная, можно сказать тут и онлайн бесплатные распозновалки отработают на 100%.

    Готовые решения думаю гуглятся, помоему даже в AForgeNet есть). - https://www.codeproject.com/Articles/11285/Neural-...

    Компьютерное зрение, готовое API - https://azure.microsoft.com/ru-ru/services/cogniti...

    Но да, первый раз сложно доходит, но как только один раз заведете это дело, то потом уже в разы проще будет.
    Ответ написан
    1 комментарий
  • Какие данные приходят на устройство через COM-порт, если отправить "1"?

    @Mercury13
    Программист на «си с крестами» и не только
    Перед нами такая конструкция
    0 . 1000 . 1100 . 1 . 0 . 0101 . 0000 . 1
    Каждый байт начинается стартовым битом 0 и кончается стоповым битом 1. Передаётся, начиная с младшего бита.
    Итого два байта, 31+0A, или "1" + LineFeed.
    Ответ написан
    9 комментариев
  • Как изменить фон у button по Click при реализованном новом шаблоне?

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

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