Задать вопрос
  • С# Taks и Invoke почему то блокируется форма?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Посмотри как я реализовал класс Analyzer, напиши свой алгоритм по такому же принципу. Внимательно прочитай комментарии в коде класса. Почитай про события в C#. Напиши отдельный класс с алгоритмом, который генерирует события, а уже в форме подпишись на события и обновляй UI. Сообщения из алгоритма отправляй через контекст синхронизации, в алгоритме не дожидайся завершения работы обработчика события (метод Post у контекста синхронизации потоков). Не пиши весь код в методах обработчиках событий форм (окон).

    В классе Analyzer
    await Task.Delay(250);
    просто для имитации долгой работы.

    Код ниже слегка отличается от кода по ссылке.
    using System;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace ProgressBarExample
    {
        internal class Analyzer
        {
            private readonly SynchronizationContext _synchronizationContext;
    
            public Analyzer()
            {
                // Если экземпляр класса будет создан в UI потоке,
                // то здесь будет контекст синхронизации UI потока, иначе пула потоков
                _synchronizationContext = SynchronizationContext.Current ?? new SynchronizationContext();
            }
    
            public event EventHandler<AnalyzerEventArgs> ProgressChanged;
    
            public Task<Data> DoWork()
            {
                return Task.Run(async () =>
                {
                    for (int i = 0; i < 100; i++)
                    {
                        // Имитация долгой работы
                        await Task.Delay(250);
                        // Здесь ты можешь так же как в своём коде вызывать OnProgressChanged
                        // раз в несколько миллисекунд. В форме в UI потоке без Invoke обрабатывать 
                        // событие, выводя те данные, которые ты поместишь в AnalyzerEventArgs
                        OnProgressChanged(new AnalyzerEventArgs("line " + (i + 1), 100));
                    }
                    return new Data() { Text = "Данные " };
                });
            }
    
            private void OnProgressChanged(AnalyzerEventArgs args)
            {
                // Перенаправляем выполнение в UI поток не ожидая пока отработает метод обработчик события.
                _synchronizationContext.Post(state =>
                {
                    ProgressChanged?.Invoke(this, (AnalyzerEventArgs)state);
                }, args); // args передаётся в переменную state (грубо говоря)
            }
        }
    }


    namespace ProgressBarExample
    {
        public class AnalyzerEventArgs
        {
            public int MaxLines { get; }
    
            public string CurrentLine { get; }
    
            public AnalyzerEventArgs(string currentLine, int maxLines)
            {
                CurrentLine = currentLine;
                MaxLines = maxLines;
            }
        }
    }


    namespace ProgressBarExample
    {
        public class Data
        {
            public string Text { get; set; }
        }
    }


    По ссылке полный код WPF приложения (не важно какой проект, в Windows Forms всё так же будет работать).
    Как сделать, чтобы ProgressBar работал во время нагрузки на приложение?
    Ответ написан
    1 комментарий
  • Как в DataGrid задать оформление определенному полю?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Сюда нельзя выложить много кода, остальное в комментариях. Этот пример не сильно опирается на Mvvm, так что в коде окна расположена коллекция, а не вью модели. Используется библиотека MvvmLight.

    Views/MainWindow.xaml
    <Window
        x:Class="WpfDataGrid.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:system="clr-namespace:System;assembly=mscorlib"
        xmlns:viewModels="clr-namespace:WpfDataGrid.ViewModels"
        Title="MainWindow"
        Width="800"
        Height="450"
        DataContext="{Binding Mode=OneWay, RelativeSource={RelativeSource Self}}"
        WindowStartupLocation="CenterScreen"
        mc:Ignorable="d">
        <Window.Resources>
    
            <SolidColorBrush
                x:Key="BackgroundOfSelectedDataGridRow"
                Color="#B6B6B6" />
            <SolidColorBrush
                x:Key="BorderBrushOfSelectedDataGridRow"
                Color="#FF2485C9" />
            <SolidColorBrush
                x:Key="ForegroundOfSeletedDataGridRow"
                Color="Black" />
    
            <SolidColorBrush
                x:Key="GridLinesBrush"
                Color="#FFB0B0B0" />
    
            <FontFamily x:Key="DefaultFontFamylyKey">
                Microsoft Sans Serif
            </FontFamily>
    
            <Style
                x:Key="DefaultDataGridCellStyle"
                TargetType="{x:Type DataGridCell}">
                <Style.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter Property="Background" Value="#B2FFD0A2" />
                        <Setter Property="BorderBrush" Value="#99FFE5CC" />
                        <Setter Property="Foreground" Value="Black" />
                    </Trigger>
                </Style.Triggers>
            </Style>
            <Style
                x:Key="DataGridStyle"
                TargetType="{x:Type DataGrid}">
                <Setter Property="RowBackground" Value="#FFE6E6E6" />
                <Setter Property="AlternatingRowBackground" Value="#FFF1F1F1" />
                <Setter Property="AlternationCount" Value="2" />
                <Setter Property="HorizontalGridLinesBrush" Value="{StaticResource GridLinesBrush}" />
                <Setter Property="VerticalGridLinesBrush" Value="{StaticResource GridLinesBrush}" />
                <Setter Property="FontFamily" Value="{StaticResource DefaultFontFamylyKey}" />
                <Setter Property="FontSize" Value="15" />
                <Setter Property="SelectionMode" Value="Single" />
                <Setter Property="RowStyle">
                    <Setter.Value>
                        <Style TargetType="{x:Type DataGridRow}">
                            <Style.Triggers>
    
                                <Trigger Property="IsMouseOver" Value="True">
                                    <Setter Property="Background" Value="{StaticResource BackgroundOfSelectedDataGridRow}" />
                                    <Setter Property="BorderBrush" Value="{StaticResource BorderBrushOfSelectedDataGridRow}" />
                                    <Setter Property="Foreground" Value="{StaticResource ForegroundOfSeletedDataGridRow}" />
                                    <Setter Property="Tag" Value="{Binding}" />
                                </Trigger>
    
                                <Trigger Property="IsSelected" Value="True">
                                    <Setter Property="Background" Value="#B2FFD0A2" />
                                    <Setter Property="BorderBrush" Value="#99FFE5CC" />
                                    <Setter Property="Foreground" Value="Black" />
                                </Trigger>
    
                            </Style.Triggers>
                        </Style>
    
                    </Setter.Value>
                </Setter>
    
                <Setter Property="CellStyle" Value="{StaticResource DefaultDataGridCellStyle}" />
    
            </Style>
        </Window.Resources>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
    
            <DataGrid
                Margin="10,10,10,0"
                AutoGenerateColumns="False"
                ItemsSource="{Binding Collection}"
                Style="{StaticResource DataGridStyle}">
                <DataGrid.ItemsPanel>
                    <ItemsPanelTemplate>
                        <VirtualizingStackPanel
                            IsVirtualizing="True"
                            VirtualizationMode="Recycling" />
                    </ItemsPanelTemplate>
                </DataGrid.ItemsPanel>
    
                <DataGrid.Columns>
                    <DataGridTemplateColumn
                        x:Name="PropertiesUpdateIndicatorColumn"
                        CanUserReorder="False"
                        CanUserResize="False"
                        CanUserSort="False"
                        IsReadOnly="True">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate DataType="viewModels:ItemViewModel">
                                <Rectangle Fill="{Binding IsChecked, Converter={StaticResource BooleanToBrushConverter}}" />
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                        <DataGridTemplateColumn.CellEditingTemplate>
                            <DataTemplate DataType="viewModels:ItemViewModel">
                                <TextBlock Text="{Binding IsChecked, UpdateSourceTrigger=PropertyChanged}" />
                            </DataTemplate>
                        </DataGridTemplateColumn.CellEditingTemplate>
                    </DataGridTemplateColumn>
    
                    <DataGridTemplateColumn
                        Width="50"
                        ClipboardContentBinding="{x:Null}"
                        Header="Выбран">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate DataType="viewModels:ItemViewModel">
                                <CheckBox
                                    HorizontalContentAlignment="Center"
                                    VerticalContentAlignment="Center"
                                    IsChecked="{Binding IsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                        <DataGridTemplateColumn.HeaderTemplate>
                            <ItemContainerTemplate>
                                <TextBlock
                                    Text=""
                                    ToolTip="{Binding Path=Text, RelativeSource={RelativeSource Self}}"
                                    ToolTipService.HasDropShadow="False"
                                    ToolTipService.Placement="Relative">
                                    <TextBlock.Resources>
                                        <Style TargetType="ToolTip">
                                            <Setter Property="VerticalOffset" Value="-1" />
                                            <Setter Property="HorizontalOffset" Value="-1" />
                                            <Setter Property="OverridesDefaultStyle" Value="True" />
                                            <Setter Property="HasDropShadow" Value="False" />
                                        </Style>
                                    </TextBlock.Resources>
                                </TextBlock>
                            </ItemContainerTemplate>
                        </DataGridTemplateColumn.HeaderTemplate>
                    </DataGridTemplateColumn>
    
                    <DataGridTemplateColumn
                        x:Name="TitleColumn"
                        ClipboardContentBinding="{x:Null}"
                        Header="Название"
                        SortMemberPath="Title">
                        <DataGridTemplateColumn.HeaderTemplate>
                            <ItemContainerTemplate>
                                <TextBlock
                                    Text="Название"
                                    ToolTip="{Binding Path=Text, RelativeSource={RelativeSource Self}}"
                                    ToolTipService.HasDropShadow="False"
                                    ToolTipService.Placement="Relative">
                                    <TextBlock.Resources>
                                        <Style TargetType="ToolTip">
                                            <Setter Property="VerticalOffset" Value="-1" />
                                            <Setter Property="HorizontalOffset" Value="-1" />
                                            <Setter Property="OverridesDefaultStyle" Value="True" />
                                            <Setter Property="HasDropShadow" Value="False" />
                                        </Style>
                                    </TextBlock.Resources>
                                </TextBlock>
                            </ItemContainerTemplate>
                        </DataGridTemplateColumn.HeaderTemplate>
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Title, Mode=OneWay}" />
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                        <DataGridTemplateColumn.CellEditingTemplate>
                            <DataTemplate>
                                <TextBox
                                    MaxLength="120"
                                    Text="{Binding Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                            </DataTemplate>
                        </DataGridTemplateColumn.CellEditingTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
            </DataGrid>
    
            <Button
                Grid.Row="1"
                Width="75"
                Margin="10,6,0,10"
                HorizontalAlignment="Left"
                VerticalAlignment="Top"
                Click="OnDeleteButtonClick"
                Content="Delete" />
        </Grid>
    </Window>
    Ответ написан
  • Как вставить векторное изображение в WPF окно?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Изображение можно увеличить (кликни или открой в новой вкладке). XAML код отформатирован расширением XamlStyler.

    5f9489198d002927078688.png

    <Window
        x:Class="WpfVectorImage.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:icons="clr-namespace:WpfVectorImage.Icons"
        xmlns:local="clr-namespace:WpfVectorImage"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        Title="MainWindow"
        Width="800"
        Height="450"
        mc:Ignorable="d">
        <Grid>
            <icons:DumbbellIcon />
        </Grid>
    </Window>


    Нельзя сюда выложить иконку, которая на скриншоте, слишком много символов.
    DumbbellIcon.xaml (иконка)
    <UserControl
        x:Class="WpfVectorImage.Icons.DumbbellIcon"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:local="clr-namespace:WpfVectorImage.Icons"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        d:DesignHeight="450"
        d:DesignWidth="800"
        mc:Ignorable="d">
    
        <Viewbox Stretch="Uniform">
            <Canvas
                Name="Layer_1"
                Width="512"
                Height="512">
                <Canvas.RenderTransform>
                    <TranslateTransform X="0" Y="0" />
                </Canvas.RenderTransform>
                <Canvas.Resources />
                <Canvas Name="g79">
                    <Canvas Name="g73">
    
                    </Canvas>
                </Canvas>
            </Canvas>
        </Viewbox>
    </UserControl>
    Ответ написан
    Комментировать
  • Как в .NET Core под Linux парсить Word/Excel?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Для Excel есть ClosedXML.

    Так же есть NPOI. Сам не использовал, но, похоже, он годится и для Excel и для Word.
    Ответ написан
    Комментировать
  • C# или Python под Linux и Windows?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    C# + AvaloniaUI (почти один в один как WPF), если нужен UI под Linux, Windows и macOS.
    Если в Windows 10 не установлен .NET Core или .NET Framework, то Windows сама предлагает всё установить, при первом запуске приложения. Нет с этим проблем. Ничего не нужно искать, читать, просто соглашаешься и всё само ставится. Это если без инсталлятора.
    Ответ написан
    Комментировать
  • PlayStation 4 бандлы. Нужно устанавливать весь бандл или можно игры из него по отдельности?

    Casper-SC
    @Casper-SC Автор вопроса
    Программист (.NET)
    Выяснилось, что игры по отдельности
    Ответ написан
    Комментировать
  • Что не так в коде?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    1. Стиль именования какой-то странный и смешанный. Можно глянуть здесь, как нужно оформлять код (не навязываю, но это именно тот стиль, в котором написан .NET Core и прочий дотнет):
    Как можно проверить,что цифры числа расположены в возрастающем порядке или в убывающем?
    Как осуществить переход между страницами в Windows Presentation Foundation? (только закомментированный оставлять не нужно, здесь для примера)
    Как сделать считывание с input и вывод в output на C#?
    Не используй русские символы, транслит, и префиксы. Не оставляй гигантские пробелы между методами.

    2. async void processing. Здесь нужно возвращать Task и он должен ожидаться в месте вызова, даже если на этом заканчивается работа метода. Если этот код вызывается по клику, то что будет если кликнуть 2 или 10 раз?

    3. Метод processing не меняет значения текстовых полей, в коде идёт присвоение значений параметрам, но эти значения не попадут в текстовые поля в окне.

    4. Магические переменные i и v. Нужно давать понятные названия.

    int i = CarNumber.Length; // Я уже переименовал и свойства
    int v = CarMark.Length;


    5. Здесь вообще Task не нужен на такой задаче, если это примерно то кол-во данных, которое будет обрабатываться.

    6. Если бы даже код был написан так, что значения бы присваивались текстовым полям в окне, то приложение бы крашилось из-за обращения к UI элементам из не UI потока.

    7. Впечатление, что автор кода думает, что может быть ошибка в коде и переменная станет меньше нуля. Зачем здесь <=, если должно быть ==?
    if (i <= 0)
    {
        dataProperty = $"Данной машины не найдено на парковке";
        dataPlace = $"Повторите попытку";
    }


    8. Здесь не нужен знак $.
    $"Данной машины не найдено на парковке";

    9. В принципе класс-парсер построен неправильно.
    Ответ написан
    Комментировать
  • Как проверить начинается ли строка с пробела c#?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    string text = "   ssd";
    if (text.StartsWith(" "))
    {
    }
    Ответ написан
    Комментировать
  • Как осуществить переход между страницами в Windows Presentation Foundation?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Microsoft Docs: How to: Navigate to a Page
    Microsoft Docs: NavigationWindow Class
    Хабр: WPF Navigation: Используем связку Page + Frame

    namespace PageNavigation.Services
    {
        public interface INavigationService
        {
            void NavigateToPage1();
    
            void NavigateToPage2();
        }
    }


    using System.Windows.Controls;
    using PageNavigation.Pages;
    
    namespace PageNavigation.Services
    {
        public class NavigationService : INavigationService
        {
            private readonly Frame _frame;
    
            public NavigationService(Frame frame)
            {
                _frame = frame;
            }
    
            public void NavigateToPage1()
            {
                _frame.Navigate(new Page1());
            }
    
            public void NavigateToPage2()
            {
                _frame.Navigate(new Page2());
            }
        }
    }


    Такой Ioc:
    using System.Windows.Controls;
    
    namespace PageNavigation.Services
    {
        public static class Ioc
        {
            public static INavigationService NavigationService { get; private set; }
    
            public static void Init(Frame frame)
            {
                NavigationService = new NavigationService(frame);
            }
        }
    }


    Или такой Ioc:
    https://autofac.org/
    using System.Windows.Controls;
    using Autofac;
    
    namespace PageNavigation.Services
    {
        public static class Ioc
        {
            private static IContainer _container;
    
            public static INavigationService NavigationService
            {
                get { return _container.Resolve<INavigationService>(); }
            }
    
            //public static MainViewModel MainViewModel
            //{
            //    get { return _container.Resolve<MainViewModel>(); }
            //}
    
            public static void Init(Frame frame)
            {
                var builder = new ContainerBuilder();
                
                builder.RegisterType<NavigationService>()
                    .As<INavigationService>()
                    .SingleInstance()
                    .WithParameter(new TypedParameter(typeof(Frame), frame));
    
                //builder.RegisterType<MainViewModel>()
                //    .SingleInstance();
    
                _container = builder.Build();
            }
        }
    }


    Главное окно XAML
    <Window
        x:Class="PageNavigation.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        Title="MainWindow"
        Width="525"
        Height="350"
        Loaded="OnLoaded"
        WindowStartupLocation="CenterScreen"
        mc:Ignorable="d">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="266*" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
    
            <Frame x:Name="_frame" />
    
            <StackPanel
                Grid.Row="1"
                Margin="8,0,0,6"
                Orientation="Horizontal">
    
                <Button
                    MinWidth="75"
                    MinHeight="29"
                    HorizontalAlignment="Left"
                    VerticalAlignment="Top"
                    Click="OnNavigateToPage1ButtonClick"
                    Content="Page1" />
    
                <Button
                    MinWidth="75"
                    MinHeight="29"
                    Margin="8,0,0,0"
                    HorizontalAlignment="Left"
                    VerticalAlignment="Top"
                    Click="OnNavigateToPage2ButtonClick"
                    Content="Page2" />
            </StackPanel>
        </Grid>
    </Window>


    Главное окно C#
    using System.Windows;
    using PageNavigation.Services;
    
    namespace PageNavigation
    {
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void OnLoaded(object sender, RoutedEventArgs e)
            {
                Ioc.Init(_frame);
            }
    
            private void OnNavigateToPage1ButtonClick(object sender, RoutedEventArgs e)
            {
                Ioc.NavigationService.NavigateToPage1();
            }
    
            private void OnNavigateToPage2ButtonClick(object sender, RoutedEventArgs e)
            {
                Ioc.NavigationService.NavigateToPage2();
            }
        }
    }


    Страница 1 XAML
    <Page
        x:Class="PageNavigation.Pages.Page1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        Title="Page1"
        d:DesignHeight="300"
        d:DesignWidth="300"
        mc:Ignorable="d">
    
        <Grid>
    
            <TextBlock Margin="5">
                Это Page 1
            </TextBlock>
    
            <Button
                Padding="12,3,12,3"
                HorizontalAlignment="Center"
                VerticalAlignment="Center"
                Click="OnNavigateToAnotherPageButtonClick"
                Content="Перейти на Page 2" />
        </Grid>
    </Page>


    Страница 1 C#
    using System.Windows.Controls;
    using PageNavigation.Services;
    
    namespace PageNavigation.Pages
    {
        public partial class Page1 : Page
        {
            public Page1()
            {
                InitializeComponent();
            }
    
            private void OnNavigateToAnotherPageButtonClick(object sender, System.Windows.RoutedEventArgs e)
            {
                Ioc.NavigationService.NavigateToPage2();
            }
        }
    }


    Страница 2 XAML
    <Page
        x:Class="PageNavigation.Pages.Page2"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        Title="Page2"
        d:DesignHeight="300"
        d:DesignWidth="300"
        mc:Ignorable="d">
    
        <Grid>
    
            <TextBlock Margin="5">
                Это Page 2
            </TextBlock>
    
            <Button
                Padding="12,3,12,3"
                HorizontalAlignment="Center"
                VerticalAlignment="Center"
                Click="OnNavigateToAnotherPageButtonClick"
                Content="Перейти на Page 1" />
        </Grid>
    </Page>


    Страница 2 C#
    using System.Windows;
    using System.Windows.Controls;
    using PageNavigation.Services;
    
    namespace PageNavigation.Pages
    {
        public partial class Page2 : Page
        {
            public Page2()
            {
                InitializeComponent();
            }
    
            private void OnNavigateToAnotherPageButtonClick(object sender, RoutedEventArgs e)
            {
                Ioc.NavigationService.NavigateToPage1();
            }
        }
    }
    Ответ написан
    1 комментарий
  • Дайте совет где учить Unity и C#?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Лучше книг нет ничего. Это в первую очередь, а в дополнение уже можно использовать и другие ресурсы, вроде видеокурсов. В книгах больше всего полезной и важной информации.

    Книги C#:
    Язык программирования C# 7 и платформы .NET и .NET Core | Троелсен Эндрю, Джепикс Филипп

    Видеокурсы по C#:
    Поиск курсов по C# на Stepik
    Нашёл такой видеокурс
    И ещё один, более старый, но я его смотрел и помню, что он качественный.
    Смотреть исходники .NET Core (строка поиска слева сверху)

    Какие посоветуете книги по C# и смежным технологиям для начинающего?

    Книга по Unity:
    Unity в действии | Хокинг Джозеф

    Видеокурсы по Unity:
    Поиск курсов по Unity на Udemy
    Ответ написан
    Комментировать
  • Как сделать считывание с input и вывод в output на C#?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    using System;
    using System.IO;
    
    namespace InputOutputExample
    {
        class Program
        {
            static void Main(string[] args)
            {
                string inputFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "input.txt");
                string outputFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "output.txt");
    
                using var input = new StreamReader(File.OpenRead(inputFile));
                Console.SetIn(input);
                
                using var output = new StreamWriter(File.OpenWrite(outputFile));
                Console.SetOut(output);
    
                string line = null;
                while ((line = Console.ReadLine()) != null)
                {
                    Console.WriteLine(line);
                }
            }
        }
    }


    5f539743c3eec503656175.png

    5f53974b97194787313157.png
    Ответ написан
    Комментировать
  • Какие вы знаете хорошие курсы по c# с нуля?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Книги нужно читать. Курсы нужно смотреть для закрепления уже после книг.
    Вот курс, где я многое узнал уже после книги, так как это было первое серьёзное изучение языка и я много чего не увидел или не понял из книги.
    Курс C# Base

    Главная книга:
    Язык программирования C# 7 и платформы .NET и .NET Core | Джепикс Филипп, Троелсен Эндрю

    Разработка приложений ASP.NET Core

    Книги (там нет книг по WPF и упоминания UWP):
    Какие посоветуете книги по C# и смежным технологиям для начинающего?

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

    Грубый пример проектов в решении:
    Изучение C# (.sln)
    1. Переменные, циклы (.csproj)
    2. Классы (.csproj)
    3. Наследование (.csproj)
    4. Делегаты и события (.csproj)

    Все проекты нужно именовать по-английски в стиле CamelCase. Выше просто пример, чтобы было понятно.
    Ответ написан
    Комментировать
  • Какова приемлемая скорость модульного теста?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Тесты выполняются так же как и любой другой код. Стоит искать причину в коде. Хотя из-за отсутствии инофрмации о том, что делает тест и как написан код - это просто 50/50. Я либо угадал, либо нет (в чём искать причину).
    Ответ написан
  • Как компилятор понимает, что первую функцию, которую нужно вызвать, будет именно Main()?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    В книге CLR via C# - Программирование на платформе Microsoft.NET Framework 4.5 на языке C#. 4-е издание на странице 37 в главе Исполнение кода сборки написано:
    Далее основной поток вызывает определенный в библиотеке MSCorEE.dll метод, который инициализирует CLR, загружает сборку EXE, а затем вызывает ее метод Main, в котором содержится точка входа. На этом процедура запуска управляемого приложения считается завершенной.


    Так же написано в документации Microsoft, что вызывается именно метод Main, если в качестве параметра компилятора -main не передать название другого метода.

    Документация Microsoft:
    Main() и аргументы командной строки
    Запуск приложения
    Ответ написан
    22 комментария
  • Сделать ожидание ввода данных с порта COM3?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    System.IO.Ports.SerialPort есть событие DataReceived.
    Ответ написан
    Комментировать
  • Как можно проверить,что цифры числа расположены в возрастающем порядке или в убывающем?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Обновлено
    Заметь, что если следующая цифра не соответствует условию, то все вычисления и перебор прекращаются. То есть, мы не получаем целиком массив цифр, а вычисляем цифры поочереди, после того как определили возрастает ли новая цифра или уменьшается по сравнению с предыдущей цифрой.

    using System;
    using System.Collections.Generic;
    using static Numbers.NumberAlgorithm;
    
    namespace Numbers
    {
        public static class NumberAlgorithm
        {
            public static bool AreDigitsIncreasing(int number)
            {
                int prevDigit = 0;
                int counter = 0;
                foreach (int digit in GetDigits(number))
                {
                    if (counter != 0 && prevDigit >= digit)
                    {
                        return false;
                    }
    
                    ++counter;
                    prevDigit = digit;
                }
    
                return counter > 1;
            }
    
            public static bool AreDigitsDecreasing(int number)
            {
                int prevDigit = 0;
                int counter = 0;
                foreach (int digit in GetDigits(number))
                {
                    if (counter != 0 && prevDigit <= digit)
                    {
                        return false;
                    }
    
                    ++counter;
                    prevDigit = digit;
                }
    
                return counter > 1;
            }
    
            public static IEnumerable<int> GetDigits(int source)
            {
                int digit = 0;
                int coefficient = (int)Math.Pow(10, GetCountOfDigits(source));
                do
                {
                    source -= coefficient * digit;
                    coefficient /= 10;
                    digit = source / coefficient;
    
                    yield return digit;
                } while (coefficient > 1);
            }
    
            public static int GetCountOfDigits(int number)
            {
                return number == 0 ? 1 : (int)Math.Ceiling(Math.Log10(Math.Abs(number) + 0.5));
            }
        }
    
        class Program
        {
            private const string DigitsAreIncreasing = "Цифры возрастают слева направо";
            private const string DigitsAreDecreasing = "Цифры понижаются слева направо";
            private const string DigitsAreMixed = "Цифры не упорядочены";
    
            static void Main(string[] args)
            {
                int[] numbers = { 123456789, 987654321, 2312, 0 };
                for (int i = 0; i < numbers.Length; i++)
                {
                    int number = numbers[i];
    
                    string message;
                    if (AreDigitsIncreasing(number))
                    {
                        message = DigitsAreIncreasing;
                    }
                    else if (AreDigitsDecreasing(number))
                    {
                        message = DigitsAreDecreasing;
                    }
                    else
                    {
                        message = DigitsAreMixed;
                    }
    
                    Console.WriteLine($"{(i + 1):D2}: Исходное число {number.ToString()}. {message}.");
    
                }
    
                Console.ReadKey();
            }
        }
    }
    Ответ написан
    Комментировать
  • Какие данные могут находится в переменных типа класса?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    В коде есть комментарии, которые нужно прочитать.

    Переменная типа MyClass, когда под неё выделят память будет содержать ссылку на MyClass со значением по умолчанию null.

    Данные в полях класса могут быть:
    • экземпляры классов -- class; ссылочный тип данных (Reference Type)
    • экземпляры структур -- struct, enum; тип значений (Value Type)


    Размеры типов значений
    Ссылочные типы
    Типы значений

    using System;
    
    namespace Types
    {
        public class Person
        {
            public string FirstName { get; set; }
    
            public int Age { get; set; }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                // Так как class это ссылочный тип данных (Reference Type), то
                // в стеке создаётся ссылка на экземпляр класса Person,
                // под который выделена память в области, называемой кучей (Heap).
                var person = new Person
                {
                    FirstName = "John",
                    Age = 30
                };
                // Передаём в метод ссылку. Ссылка копируется, а данные
                // так и остаются в куче, с ними ничего не происходит.
                // Данных может быть хоть мегабайт, они не копируются, а вот
                // ссылка копируется и имеет разный размер в зависимости от 
                // архитектуры x86 или x64, но размер этот крайне маленький (4 байта или 8 байт)
                Display(person);
                
                Console.ReadKey();
            }
            
            private static void Display(Person person)
            {
                // Здесь внутри метода находится копия ссылки.
                Console.WriteLine($"Name = {person.FirstName}, Age = {person.Age.ToString()}");
            }
        }
    }


    -
                // Ссылка, так как это class
                Person person; 
    
                // Ссылка на экземпляр класса, так как мы выделили память в куче.
                person = new Person();


    using System;
    
    namespace Types
    {
        class MyClass
        {
            MyClass my;
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                // Выделяем память в куче.
                // Ссылается на экземпляр класса MyClass, внутри
                // которого есть поле типа MyClass со значением null.
                MyClass data = new MyClass();
    
                Console.ReadKey();
            }
        }
    }
    Ответ написан
    Комментировать
  • Как обратиться к параметру класса?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Обратиться к полю класса можно так:

    #pragma once
    #include <string>
    
    class Window
    {
    public:
    	Window(const std::string& fileName);
    	void MaximizeWindow();
    
    private:
        std::string _fileName;
    };


    #include "Window.h"
    
    Window::Window(const std::string& fileName)
        : _fileName(fileName) {
    
    }
    
    void Window::MaximizeWindow() {
        // Здесь можно обратиться к полю _fileName
    }
    Ответ написан
  • Что лучше один ультраширокий монитор или два обычных?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Я взял 2 4К монитора 27" LG. Выставил разрешение в родное 4К и масштабирование в 150%. Красота. Места на каждом мониторе больше, чем на одном FullHD, текст чёткий.

    В играх графон в 4К на таком мониторе сильно круче, чем на FullHD мониторе, в некоторых играх прямо в разы.
    Ответ написан
    Комментировать