Контакты

Достижения

Все достижения (4)

Наибольший вклад в теги

Все теги (15)

Лучшие ответы пользователя

Все ответы (34)
  • Как динамически менять значение TextBox, если Binding идет через Dictionary?

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

    OnPropertyChanged(nameof(TextBoxes));

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

    OnPropertyChanged();

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

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


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

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

    FoggyFinder
    @FoggyFinder
    Используйте Layout-s, в вашем случае должен подойти TableLayoutPanel, который позволяет компоновать элементы управления в виде таблицы.

    Простой пример на русском языке можно найти тут:

    TableLayoutPanel
    Ответ написан
  • Можно ли комментировать локальные переменные Visual Studio [нельзя]?

    FoggyFinder
    @FoggyFinder
    Если вы имеете ввиду xml-документацию, то нельзя.

    Локальные переменные - детали реализации. Старайтесь давать самодокументируемые названия, а сложные участки кода дополнительно сопровождайте комментариями.
    Ответ написан
  • Как создать свой дизайн интерфейса в WPF?

    FoggyFinder
    @FoggyFinder
    1. "Напрямую накидывать" вероятно, нельзя. Но возможность импорта все-таки присутствует:

    How to Import Photoshop Files into WPF

    Насколько такой способ рабочий сейчас - не знаю, не проверял.

    2. Blend for Visual Studio overview

    3. Metro UI особый стиль для приложений / сайтов. Для WPF есть очень известная библиотека MahApps.Metro.

    Теперь, что касается "стилизации" - WPF в плане настройки внешнего вида элементов управления и приложений в целом очень гибкий. Можно сделать практически все. Не буду даже пытаться раскрывать тему, материалов в сети очень много, но попробую дать направление для дальнейших поисков:

    Ключевые слова:

    • Style
    • DataTemplate
    • Trigger


    Для ознакомления материал из документации:

    Styling and Templating

    А для основательного разбора рекомендую следующую литературу:

    1. WPF: Windows Presentation Foundation в .NET 4.5 с ...

    2. WPF 4. Подробное руководство


    Сам я изучал WPF по книге Макдональда, материал изложен в доступной форме, но рассмотрение подробное, а не только основы.

    Есть и онлайн ресурсы:

    1. metanit: Руководство по WPF
    2. professorweb: WPF - Windows Presentation Foundation


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



    Первые две очень широко используются.

    И напоследок небольшое отступление:

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

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

    В принципе, можете попробовать совместить F# c WPF, возможности code-behind нам намного-намного меньше ;-), а значит проще будет пойти понять шаблоны MVVM или даже Elmish.
    Ответ написан
  • Как сделать программу для заполнения данных в Word?

    FoggyFinder
    @FoggyFinder
    Не ясно почему были убрана метка "Программирование" из вопроса. Получается ответ в некотором роде будет оффтопом.

    Теперь по существу:

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

    Но если нужна именно программа, то я бы начал с составления ТЗ (технического задания), в котором было бы подробное описание требуемого функционала.

    Пока описание в вопросе довольно расплывчатое, но вот набросок который на скорую руку написал за пару часов на языке программирования F#:

    Примечание: Возможно F# не самый лучший выбор для данной задачи, но так как для своих персональных программ использую его, то и код привожу на нем.

    1. Определяются основные объекты (Студент, Преподаватель, Абитуриент) для которых в виде свойств перечисляются характеристики для заполнения:

    module Model
    
    type Student = {
        Name : string
        Surname : string
        LastName : string
        Phone : string
        Faculty : string
    }


    Отдельно, для удобства, представляем наши записи в виде размеченного объединения:

    [<RequireQualifiedAccess>]
    type AccountType = 
        | Student of Student
        | Enrollee of Enrollee
        | Teacher of Teacher


    Создаем модуль Defaults в котором будут находится значения по умолчанию для объектов (будет нужно для отображения):

    [<RequireQualifiedAccess>]
    module Defaults = 
        let student:Student = {
            Name = ""
            Surname = ""
            LastName = ""
            Phone = ""
            Faculty = ""
        }


    Следующий шаг - создание или редактирование / заполнение готового Word или Pdf шаблона данными.

    Есть несколько вариантов (библиотек) для работы и с тем и с другим форматом. Для Pdf есть очень известная библиотека:

    iTextSharp

    Есть и другие, как например,

    SharpLayout

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

    Простейший вывод в виде таблицы может выглядеть так:

    [<RequireQualifiedAccess>]
    module PdfReport
    
    open Model
    open PdfSharp.Drawing
    open SharpLayout
    
    let private defaultSettings = 
        PageSettings(
            TopMargin=Util.Cm(1.2),
            BottomMargin=Util.Cm(1.0),
            LeftMargin=Util.Cm(2.0),
            RightMargin=Util.Cm(1.0))
    
    let private createReportForTeacher teacher = 
        let document = Document()
        let section = document.Add(Section(defaultSettings))
        
        let font = 
            Font("Times New Roman", 10.0, XFontStyle.Regular, XPdfFontOptions.UnicodeDefault)
            |> Option
        
        section.Add(Paragraph().Add("Информация об преподователе", font.Value).Alignment(HorizontalAlign.Center.AsOption().ToNullable())) |> ignore
    
        let table = section.AddTable().Font font
        
        let c1 = table.AddColumn(Util.Px(600.0))
        let c2 = table.AddColumn(Util.Px(600.0))
        
        let r1 = table.AddRow()
        let r2 = table.AddRow()
        let r3 = table.AddRow()
        let r4 = table.AddRow()    
        let r5 = table.AddRow()
    
        r1.[c1].Add(Paragraph().Add("Имя:")) |> ignore
        r1.[c2].Add(Paragraph().Add(teacher.Name)) |> ignore
    
        r2.[c1].Add(Paragraph().Add("Фамилия:")) |> ignore
        r2.[c2].Add(Paragraph().Add(teacher.LastName)) |> ignore
    
        r3.[c1].Add(Paragraph().Add("Отчество:")) |> ignore
        r3.[c2].Add(Paragraph().Add(teacher.Surname)) |> ignore
    
        r4.[c1].Add(Paragraph().Add("Телефон:")) |> ignore
        r4.[c2].Add(Paragraph().Add(teacher.Phone)) |> ignore
    
        r5.[c1].Add(Paragraph().Add("Факультет:")) |> ignore
        r5.[c2].Add(Paragraph().Add(teacher.Faculty)) |> ignore
    
        document


    Теперь что касается отображения, мне удобнее использовать WPF, ссылка на руководство и библиотеку
    Gjallarhorn.Bindable.

    Для каждого типа создаем свой UserControl который будет отвечать за ввод данных.

    Каждое отображение определим в виде навигационного состояния:

    [<RequireQualifiedAccess>]
    type NavMessages = 
        | Student
        | Teacher
        | Enrollee


    работу с каждым типом вынесем в отдельные дочерние компоненты (StudentComponent, ...). Для каждого свойства можно определить собственное правило проверки корректности.

    let appComp =
        Component.create<AppModel, NavMessages, Messages> [
            <@ ctx.Model.Student @> |> Bind.comp (fun m -> m.Student) studentComp fst
            <@ ctx.Model.Enrollee @> |> Bind.comp (fun m -> m.Enrollee) enrolleeComp fst
            <@ ctx.Model.Teacher @> |> Bind.comp (fun m -> m.Teacher) teacherComp fst
                            
            <@ ctx.Model.Menu @> |> Bind.comp (fun m -> m.Menu) menuComponent fst
        
            <@ ctx.SendReport @> |> Bind.cmd
        ]


    Команда SendReport будет отвечать за созданием отчета и отправку его на почту. Кнопка будет активна только в том случае, если все поля заполнены без ошибок.

    Остается определить функцию обновления модели приложения:

    let upd (nav : Dispatcher<NavMessages>) message model = 
        match message with
        | Messages.SendReport ->
            let v, m = 
                match model.Menu.Current with
                | NavMessages.Enrollee -> 
                    AccountType.Enrollee model.Enrollee, { model with Enrollee = Defaults.enrollee }
                | NavMessages.Student -> 
                    AccountType.Student model.Student, { model with Student = Defaults.student }
                | NavMessages.Teacher -> 
                    AccountType.Teacher model.Teacher, { model with Teacher = Defaults.teacher }
            v
            |> PdfReport.createReport
            |> PdfReport.saveReport "test.pdf"
            |> PdfReport.sendReport
            m
        | Messages.SetCurrent current ->
            current |> nav.Dispatch
            { model with Menu = { model.Menu with Current = current }}
        | Messages.UpdateEnrollee msg ->
            { model with Enrollee = EnrolleeComponent.update model.Enrollee msg }
        | Messages.UpdateStudent msg ->
            { model with Student = StudentComponent.update model.Student msg }
        | Messages.UpdateTeacher msg ->
            { model with Teacher = TeacherComponent.update model.Teacher msg }
    
    open Gjallarhorn.Bindable.Framework
    
    let applicationCore nav =
        let navigation = Dispatcher<NavMessages>()
        Framework.application init (upd navigation) appComp nav
        |> Framework.withNavigation navigation


    Для работы с почтой вам нужно будет указать данные с которых вы хотите отправлять письмо. Как это сделать написано тут.

    Теперь, чтобы добавить новый тип нужно будет сделать следующее:

    1. Определить запись для нового объекта, описывающую его свойства.
    2. Создать функцию генерирующую отчет для этого типа.
    3. Создать компонент.
    4. Создать пользовательский элемент управления для отображения.
    5. Добавить его в общую модель программы.

    В итоге получилось следующее:

    5c7ece7614321212016044.gif

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

    В данном примере был записан такой pdf:

    5c7eceaae88cf238140201.jpeg

    Весь код не приводил, так как он довольно объемный, если такой вариант интересует, то могу выложить на гитхаб.

    Только учтите, что набросок можно сделать за пару часов, а довести до ума будет занимать намного больше времени.
    Ответ написан