• Почему в консоли не отображается ноль при значении переменной double менее 1?

    FoggyFinder
    @FoggyFinder
    Символ "#" в форматированной строке не отображает "незначащие" нули.

    В вашем случае, вероятно, подойдет спецификатор "0".

    Подробнее о форматировании чисел можно прочесть, например, в специальном разделе документации:

    Строки настраиваемых числовых форматов

    Позволю себе оставить пару комментариев-советов по поводу кода. Хотел оформить в виде комментария, но в виду объема и того что по каким-то причинам не подсвечивался синтаксис переношу сюда:

    1. Как вы должно быть заметили некоторая функциональность при считывании информации с консоли дублируется. Вместо того чтобы заниматься копированием однотипного участка внося минимальные изменения такие части удобнее выносить в отдельные функции.

    Например:

    public static double ReadDouble
        (string msg = "", string errMsg = "Произошла ошибка, повторите ввод")
    {
        if (!string.IsNullOrWhiteSpace(msg))
            Console.WriteLine(msg);
    
        double value;
        while (!double.TryParse(Console.ReadLine(), out value))
            Console.WriteLine(errMsg);
    
        return value;
    }


    Тогда считывание будет намного понятнее:

    var s = ReadDouble("Введи сечение кабеля, мм2: ");
    var l = ReadDouble("Введи длину кабеля, мм2: ");
    var i = ReadDouble("Введи нагрузку на конце линии, А: ");
    var u = ReadDouble("Введи значение напряжения источника, В: ");


    2. По возможности следует избегать использования "магических чисел" (как у вас - 0.018). Константы должны быть определены как константы. Вместо определения Pi как 3.1415926535 используете встроенное Math.PI.

    3. Использование полей в классе можно улучшить. Сейчас они у вас открытые и задаются извне. Если какие параметры являются обязательными, то определив соответствующий конструктор, можно не только добавить сделать класс более надежным, но и в дальнейшем сделать проверку на правильность передаваемых значений.

    public double S { get; set; }
    public double L { get; set; }
    public double I { get; set; }
    public double U { get; set; }
    
    public Technocalc(double s, double l, double i, double u)
    {
        S = s;
        L = l;
        I = i;
        U = u;
    }


    4. Методы можно упростить с более современным синтаксисом:

    public double padU => R * I;
    public double R => RConst / S * L * 2;
    public double diameter => Math.PI * S * S / 4;


    Итого, с учетом написанного выше класс будет выглядеть вот так:

    class Technocalc
        {
            public const double RConst = 0.018;
    
            public double S { get; set; }
            public double L { get; set; }
            public double I { get; set; }
            public double U { get; set; }
    
            public Technocalc(double s, double l, double i, double u)
            {
                S = s;
                L = l;
                I = i;
                U = u;
            }
    
            public double padU => R * I;
            public double R => RConst / S * L * 2;
            public double diameter => Math.PI * S * S / 4;
        }



    и вызывающий код:

    public static double ReadDouble
                (string msg = "", string errMsg = "Произошла ошибка, повторите ввод")
            {
                if (!string.IsNullOrWhiteSpace(msg))
                    Console.WriteLine(msg);
    
                double value;
                while (!double.TryParse(Console.ReadLine(), out value))
                    Console.WriteLine(errMsg);
    
                return value;
            }
            public static void Main(string[] args)
            {
                Console.WriteLine("\t\t\t\t" + "Программа расчета падения напряжения в кабеле. 2019 г. Версия 0.0.1");
                var s = ReadDouble("Введи сечение кабеля, мм2: ");
                var l = ReadDouble("Введи длину кабеля, мм2: ");
                var i = ReadDouble("Введи нагрузку на конце линии, А: ");
                var u = ReadDouble("Введи значение напряжения источника, В: ");
                Technocalc cable = new Technocalc(s, l, i, u);
    
                //вывод всей информации на экран
                Console.WriteLine();
                Console.WriteLine("\t\t\t\t" + "Параметры линии:");
                Console.WriteLine("--------------------------------------------------------------------------------");
                Console.WriteLine("Кол-во жил\t\tRкабеля, Ом\t\tСечение, мм2\t\tНапряжение,В\tВых. напряжение, В");
                Console.WriteLine("{0:#0.##}\t\t\t{1:0.0#}\t\t\t{2:0.##}\t\t\t{3:0.##}\t\t{4:0.##}", 2, cable.R, cable.S, cable.U, cable.U - cable.padU);
                Console.WriteLine("--------------------------------------------------------------------------------");
                Console.WriteLine("Rжилы , Ом\t\tДлина кабеля,м\t\tНагрузка, А\t\tПадение U, В\tДиаметр жилы, мм");
                Console.WriteLine("{0:#0.##}\t\t\t{1:#0.##}\t\t\t{2:#0.##}\t\t\t{3:#0.##}\t\t{4:#0.##}\t\t", cable.R / 2, cable.L, cable.I, cable.padU, cable.diameter);
                Console.WriteLine();
                Console.ReadKey(true);
            }
    Ответ написан
    4 комментария
  • Почему не добавляет элемент в список?

    FoggyFinder
    @FoggyFinder
    Как уже правильно указали, проблема состоит в том, что вы каждый раз создаете новый экземпляр ManagerMeeting:

    public void Route(string answer)
    {
        var manager = new ManagerMeeting();


    Также оставлю несколько комментариев по поводу кода:

    1. Наследование применяете неправильно.

    2. Если в сеттерах свойств нет дополнительной проверки на корректность значений полей, то лучше использовать авто-свойства.

    3. Слишком сложная структура - классы Menu, Route кажутся избыточными. Для таких простых сценариев методы перечисленных классов проще перенести в Program.

    4. Класс ManagerMeeting слишком сильно связан с консолью, кроме того есть зависимость от Menu. Если хотите предоставить методы для управления коллекцией (список встреч), то выставите необходимые методы и уже работайте с ними.

    5. Для форматированного вывода собственных классов удобно переопределить метод .ToString()

    Немного переписанные классы с учетом указанного выше:

    class Meetings // Класс встреч
        {
            public string DateMeeting { get; set; }
            public string StartMeeting { get; set; }
            public string EndMeeting { get; set; }
    
            public override string ToString()
            {
                return $"Дата встречи: {DateMeeting}, Начало встречи: {StartMeeting}, Конец встречи: {EndMeeting}";
            }
        }
    
        class ManagerMeeting //  Класс управление встречами
        {
            public List<Meetings> MeetingList { get; } = new List<Meetings>();
            public void Add(Meetings meet)
            {
                MeetingList.Add(meet);
            }
            public string FormatMeetings()
            {
                StringWriter sw = new StringWriter();
                foreach (var meet in MeetingList)
                    sw.WriteLine(meet);
                return sw.ToString();
            }  
        }


    меню:

    class Program
        {
            static ManagerMeeting manager = new ManagerMeeting();
            public static void ShowMainMenu()
            {
                Console.WriteLine("Выберите действие: \n1. Показать все встречи\n2. Создать новую встречу");
            }
    
            public static bool Handler()
            {
                Console.Clear();
                ShowMainMenu();
                string answer = Console.ReadLine();
                switch (answer)
                {
                    case "1":
                        var result = manager.FormatMeetings();
                        if (string.IsNullOrWhiteSpace(result))
                            Console.WriteLine("Список пуск");
                        else
                            Console.WriteLine(manager.FormatMeetings());
                        return true;
                    case "2":
                        manager.Add(ReadMeeting());
                        return true;
                    default:
                        return false;
                }
            }
    
            public static void Main(string[] args)
            {
                while (Handler()) Console.ReadKey(true);
                Console.ReadKey(true);
            }
    
            public static Meetings ReadMeeting()
            {
                Console.WriteLine("Введите дату встречи:");
                var date = Console.ReadLine();
                Console.WriteLine("Введите время начала встречи:");
                var startMeeting = Console.ReadLine();
                Console.WriteLine("Введите время конца встречи:");
                var endMeeting = Console.ReadLine();
    
                Console.WriteLine("Встреча добавлена! \n ");
                //Для проверки, записываются ли поля - записываются
                Console.WriteLine(date + startMeeting + endMeeting);
                return new Meetings
                {
                    DateMeeting = date,
                    StartMeeting = startMeeting,
                    EndMeeting = endMeeting
                };
            }
        }


    Конечно, код выше тоже далек от идеального (всегда есть что улучшать). Например,:

    Предусмотрите проверку данных:

    В считывания информации с консоли:
    * используйте типы данных которые лучше всего подходят для описания свойств (DateTime для даты и времени вместо универсального string)
    * напишите вспомогательные методы GetInteger, GetDateTime и другие которые будут возвращать результат только после того как пользователь ввел корректные данные.

    В классе ManagerMeeting:

    * Пусть вместо void метод Add -возвращает bool в зависимости от успешности добавления (например, чтобы предусмотреть сценарии добавления давно прошедшей встречей).

    И так далее.
    Ответ написан
    2 комментария
  • Можно ли на WPF создавать самостоятельные приложения для частного использования?

    FoggyFinder
    @FoggyFinder
    Поняла, да не до конца. Что еще нужно, чтобы сделать цельное приложение


    Все зависит от самого приложения.

    Назовите плиз примеры из жизни для приложений, которые можно написать используя это фреймворк.


    Их очень много. Приведу несколько OpenSource приложений которые использую или использовал раньше:

    Snoop
    ScreenToGif
    MarkdownMonster
    LiteDbExplorer

    Эти приложения могут индивидуально писаться под заказ как сайты к примеру


    Могут и пишутся.
    Ответ написан
    Комментировать
  • C# WPF Графика. Пересечение фигур. Как привести Polygon в Geometry?

    FoggyFinder
    @FoggyFinder
    По сути ваш вопрос содержит два отдельных вопроса:

    1. Как найти пересечение полигонов.
    2. Как преобразовать Polygon к Geometry.

    Отвечаю на второй:

    За определение сложных геометрических фигур отвечает класс PathFigure. Нужно определить начальную точку и последовательность сегментов (в нашем случае - LineSegment)

    var s1 = p1.Points.Skip(1).Select(p => new LineSegment { Point = p } );
    var g1 = new PathFigure(p1.Points.First(), s1, true);


    где p1 - первый полигон.

    Со вторым поступаем аналогично, ну а дальше вы уже знаете

    var path1 = new PathGeometry(new[] { g1 });
    var path2 = new PathGeometry(new[] { g2 });
    
    var path = new Path()
    {
        Data = new CombinedGeometry(GeometryCombineMode.Intersect, path1, path2),
        Fill = Brushes.Green
    };
    Ответ написан
    Комментировать
  • Как привязать данные разного типа к одному элементу управления и выводить в зависимости от определенного условия?

    FoggyFinder
    @FoggyFinder
    Возможно вам подойдут триггеры данных.

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

    <ListBox ItemsSource="{Binding CurrentData}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding .}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
        <ListBox.Style>
            <Style TargetType="ListBox">
                <Style.Triggers>
                    <Trigger Property="HasItems" Value="False">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate>
                                    <TextBlock
                                        Margin="5"
                                        HorizontalAlignment="Center"
                                        VerticalAlignment="Center"
                                        FontSize="16"
                                        Text="{Binding StringIfEmpty}" />
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </ListBox.Style>
    </ListBox>
    Ответ написан
    Комментировать