Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.80/15: Рейтинг темы: голосов - 15, средняя оценка - 4.80
15 / 4 / 2
Регистрация: 16.04.2019
Сообщений: 112

Реализация приложения "Калькулятор НДС"

06.11.2021, 06:21. Показов 3746. Ответов 41
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Тема создана разделением темы: MessageBox в MVVM

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Это скорее вам про делегаты надо прочитать.
Обратный вызов - это частный случай использования делегатов.
Делегаты (Руководство по программированию на C#)
С# и .NET | Делегаты - Metanit
Руководство C# | Делегаты - Professor Web
Спасибо большое, прежде чем осваивать информацию, которую вы мне дали, я написал небольшой проект НДС калькулятор, если Вам не сложно, можете посмотреть его? Правильно ли я осуществляю передачу данных в модель и возвращаю результат?
Вложения
Тип файла: zip NDS.zip (504.0 Кб, 9 просмотров)
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
06.11.2021, 06:21
Ответы с готовыми решениями:

Расчёт цены с НДС (цена и НДС указываются при вызове функции (не метода)
Здравствуйте, Очень прошу о помощи! Мне нужно написать функцию, именно функцию, а не метод, которая возвращает цену с НДС. ...

Дана цена товара в долларах с НДС; посчитать эту цену в рублях без НДС
Добра вам, уважаемые господа-программисты и не только:gsmile:! Пытаюсь решить задачку на денежные единицы, и тут я поняла, что мне не быть...

SEO-фирма с НДС или без НДС?
Приветствую! Возникла трудность. Насколько я знаю в случае работы без НДС многим фирмам получается не выгодно (если они платят НДС, не...

41
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16444 / 11287 / 2892
Регистрация: 21.04.2018
Сообщений: 33,184
Записей в блоге: 2
09.11.2021, 00:26
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от salaga2019 Посмотреть сообщение
Разобрался!
Молодцом!

Теперь вышлите мне приглашение на соавторство.
И завтра продолжим.


На данный момент всё понятно?
0
15 / 4 / 2
Регистрация: 16.04.2019
Сообщений: 112
09.11.2021, 00:31  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
как разберётесь - киньте мне приглашение в соавторы: EldHasp - аватарка как здесь на Форуме.
Добавил.

Добавлено через 1 минуту
Цитата Сообщение от Элд Хасп Посмотреть сообщение
На данный момент всё понятно?
Пока да, все понятно, если что, гуглю.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16444 / 11287 / 2892
Регистрация: 21.04.2018
Сообщений: 33,184
Записей в блоге: 2
09.11.2021, 09:10
salaga2019, продолжаем.

У вас какой-то сборник в реализации INPC одни и те же методы по нескольку раз реализованы с разными именами.
Поэтому добавил библиотеку с реализацией: Простые реализации для тем на форуме .

VM сначала объявляем класс, отчего он наследуется и какие интерфейсы реализует.
C#
6
    public class MainWindowViewModel : BaseInpc, INdsCalculationViewModel
Интерфейс подчёркнут красной чертой. В быстрых решениях выбираем "Реализовать интерфейс".
Получаем такую рыбу:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
using NDSCalc.ViewModel.Interfaces;
using Simplified;
 
namespace NDSCalc.ViewModel.Windows
{
    public class MainWindowViewModel : BaseInpc, INdsCalculationViewModel
    {
        public decimal AmountWithoutNds { get; set; }
        public decimal NdsRate { get; set; }
        public decimal AmountOfNds { get; }
        public decimal TotalAmount { get; }
    }
}
Добавляем приватные сеттеры свойствам в которых их нет и делаем полную реализацию свойств:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using NDSCalc.ViewModel.Interfaces;
using Simplified;
 
namespace NDSCalc.ViewModel.Windows
{
    public class MainWindowViewModel : BaseInpc, INdsCalculationViewModel
    {
        private decimal _amountWithoutNds;
        private decimal _ndsRate;
        private decimal _amountOfNds;
        private decimal _totalAmount;
 
        public decimal AmountWithoutNds { get => _amountWithoutNds; set => Set(ref _amountWithoutNds, value); }
        public decimal NdsRate { get => _ndsRate; set => Set(ref _ndsRate, value); }
        public decimal AmountOfNds { get => _amountOfNds; private set => Set(ref _amountOfNds, value); }
        public decimal TotalAmount { get => _totalAmount; private set => Set(ref _totalAmount, value); }
    }
}
Отправил Фиксацию 617a8f92:
Сделана реализация интерфейса VM.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16444 / 11287 / 2892
Регистрация: 21.04.2018
Сообщений: 33,184
Записей в блоге: 2
09.11.2021, 10:25
salaga2019, эту реализацию уже можно использовать для создания GUI (View) и проверки её компонентов.
Для этого создадим демо вариант VM.
Добавляем статический экземпляр в VM:
C#
18
19
20
21
22
23
24
        public static MainWindowViewModel DemoInstance { get; } = new MainWindowViewModel()
        {
            AmountWithoutNds = 123.45m,
            NdsRate = 67.8m,
            AmountOfNds = 90.12m,
            TotalAmount = 345.67m
        };
Переходим к View и там задаём использование этого демо-экземпляра:
XML
9
        DataContext="{x:Static vm:MainWindowViewModel.DemoInstance}">
Добавляем разметку Окна:
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<Window x:Class="NDSCalc.View.Windows.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:vm="clr-namespace:NDSCalc.ViewModel.Windows;assembly=NDSCalc.ViewModel"
        xmlns:controls="clr-namespace:NDSCalc.View.Controls"
        mc:Ignorable="d"
        WindowStartupLocation="CenterScreen"
        DataContext="{x:Static vm:MainWindowViewModel.DemoInstance}"
        xmlns:Themes1="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
        Background="DarkGray"
        SizeToContent="WidthAndHeight">
    <FrameworkElement.Resources>
        <Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource main.TextBlock}"/>
        <Style TargetType="{x:Type Label}" BasedOn="{StaticResource main.Label}"/>
        <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource InputTextBox.Style}"/>
        <Style TargetType="{x:Type controls:InputTextBoxStakeNDSControl}" BasedOn="{StaticResource InputTextBox.Style}"/>
    </FrameworkElement.Resources>
    <Grid Margin="0,0,50,0">
        <Grid.RowDefinitions>
            <RowDefinition Height="60"/>
            <RowDefinition Height="60"/>
            <RowDefinition Height="60"/>
            <RowDefinition Height="60"/>
            <RowDefinition Height="60"/>
            <RowDefinition Height="60"/>
            <RowDefinition Height="150"/>
            <RowDefinition Height="150"/>
            <RowDefinition Height="150"/>
        </Grid.RowDefinitions>
        <Label Grid.Row="0" Content="Выделить НДС"/>
        <Grid Grid.Row="1" Height="30">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="150"/>
                <ColumnDefinition Width="400"/>
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0" Text="Сумма без НДС:"/>
            <controls:InputTextBoxControl Grid.Column="1" 
                                          Text="{Binding AmountWithoutNds, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
 
        </Grid>
        <Grid Grid.Row="2" Height="30">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="150"/>
                <ColumnDefinition Width="400"/>
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0" Text="Ставка НДС:"/>
            <controls:InputTextBoxStakeNDSControl Grid.Column="1"
                                                  Text="{Binding NdsRate, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
        </Grid>
        <Grid Grid.Row="3" Height="30">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="150"/>
                <ColumnDefinition Width="400"/>
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0" Text="Общая сумма:"/>
            <TextBox Grid.Column="1"  Text="{Binding TotalAmount, Mode=OneWay}" IsReadOnly="True"/>
        </Grid>
        <Grid Grid.Row="4" Height="30">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="150"/>
                <ColumnDefinition Width="400"/>
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0" Text="Сумма НДС:"/>
            <TextBox Grid.Column="1" Text="{Binding AmountOfNds, Mode=OneWay}" IsReadOnly="True"/>
        </Grid>
        <Label Grid.Row="5" Content="Числа прописью"/>
        <Grid Grid.Row="6" Margin="0 0 0 15">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="150"/>
                <ColumnDefinition Width="400"/>
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0" Text="Сумма:"/>
            <TextBox Grid.Column="1" Style="{StaticResource InputTextBox.Style}" BorderThickness="2" Margin="0 5 0 0"
                     Text="{Binding TotalAmount, Mode=OneWay}" IsReadOnly="True" Height="120" VerticalAlignment="Top" VerticalContentAlignment="Top" TextWrapping="Wrap"/>
        </Grid>
        <Grid Grid.Row="7" Margin="0 0 0 15">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="150"/>
                <ColumnDefinition Width="400"/>
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0" Text="Без НДС:"/>
            <TextBox Grid.Column="1" Style="{StaticResource InputTextBox.Style}" BorderThickness="2" Margin="0 5 0 0"
                     Text="{Binding AmountWithoutNds}" IsReadOnly="True" Height="120" VerticalAlignment="Top" VerticalContentAlignment="Top" TextWrapping="Wrap"/>
        </Grid>
        <Grid Grid.Row="8">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="150"/>
                <ColumnDefinition Width="400"/>
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0" Text="НДС:"/>
            <TextBox Grid.Column="1" Style="{StaticResource InputTextBox.Style}" BorderThickness="2" Margin="0 5 0 0"
                     Text="{Binding AmountOfNds, Mode=OneWay}" IsReadOnly="True" Height="120" VerticalAlignment="Top" VerticalContentAlignment="Top" TextWrapping="Wrap"/>
        </Grid>
    </Grid>
</Window>
Добавлено через 29 минут
Теперь нужно добавить конвертер выдающий сумму прописью.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using System.Windows.Markup;
 
namespace NDSCalc.View.Converters
{
    [ValueConversion(typeof(decimal), typeof(string))]
    public class NumberInWordsConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (!(value is decimal amount))
            {
                if (!decimal.TryParse(string.Format(culture, "{0}", value), NumberStyles.Any, culture, out amount))
                {
                    return DependencyProperty.UnsetValue;
                }
            }
 
            return AmountInWords.CurrencyToTxt(amount, true);
        }
 
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
 
        public static NumberInWordsConverter Instance { get; } = new NumberInWordsConverter();
    }
 
    [MarkupExtensionReturnType(typeof(NumberInWordsConverter))]
    public class NumberInWordsConverterExtension : MarkupExtension
    {
        public override object ProvideValue(IServiceProvider serviceProvider)
            => NumberInWordsConverter.Instance;
    }
 
}
Добавляем конвертер к привязкам:
XML
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
        <Grid Grid.Row="6" Margin="0 0 0 15">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="150"/>
                <ColumnDefinition Width="400"/>
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0" Text="Сумма:"/>
            <TextBox Grid.Column="1" Style="{StaticResource InputTextBox.Style}" BorderThickness="2" Margin="0 5 0 0"
                     Text="{Binding TotalAmount, Mode=OneWay, Converter={converters:NumberInWordsConverter}}"
                     IsReadOnly="True" Height="120" VerticalAlignment="Top" VerticalContentAlignment="Top" TextWrapping="Wrap"/>
        </Grid>
        <Grid Grid.Row="7" Margin="0 0 0 15">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="150"/>
                <ColumnDefinition Width="400"/>
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0" Text="Без НДС:"/>
            <TextBox Grid.Column="1" Style="{StaticResource InputTextBox.Style}" BorderThickness="2" Margin="0 5 0 0"
                     Text="{Binding AmountWithoutNds, Mode=OneWay, Converter={converters:NumberInWordsConverter}}"
                     IsReadOnly="True" Height="120" VerticalAlignment="Top" VerticalContentAlignment="Top" TextWrapping="Wrap"/>
        </Grid>
        <Grid Grid.Row="8">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="150"/>
                <ColumnDefinition Width="400"/>
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0" Text="НДС:"/>
            <TextBox Grid.Column="1" Style="{StaticResource InputTextBox.Style}" BorderThickness="2" Margin="0 5 0 0"
                     Text="{Binding AmountOfNds, Mode=OneWay, Converter={converters:NumberInWordsConverter}}"
                     IsReadOnly="True" Height="120" VerticalAlignment="Top" VerticalContentAlignment="Top" TextWrapping="Wrap"/>
        </Grid>
На этом разработка View закончена.
Осталось добавить в ViewModel связь с Моделью.
Пока разберитесь с этим.
Потом продолжим.

Сделал Фиксацию f9b3725a.
0
15 / 4 / 2
Регистрация: 16.04.2019
Сообщений: 112
09.11.2021, 11:15  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Теперь нужно добавить конвертер выдающий сумму прописью.
Сейчас пока быстро пробежался по коду, через 2 часа домой приду внимательно изучу, пока вопрос есть один:

Если программист пишет приложение с использованием паттерна MVVM, он понимает, что его приложение будут тестировать, только вот как происходит тестирование я не знаю, но оно должно быть без View, это я к чему, если тестирование будет без View, то как будет работать конвертер, который находится во View или же имеется ввиду что не будет xaml разметки, а остальные классы View будут задействованы? Вы, как человек опытный, уже понимаете что, зачем и почему вы пишете тот или иной код и создаете класс в том или ином месте, раз вы создаете конвертер во View, видимо View все равно будет участвовать при тестировании, может быть это глупый вопрос, но я думаю это очень важный момент.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16444 / 11287 / 2892
Регистрация: 21.04.2018
Сообщений: 33,184
Записей в блоге: 2
10.11.2021, 09:33
Цитата Сообщение от salaga2019 Посмотреть сообщение
что не будет xaml разметки, а остальные классы View будут задействованы?
Да.

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

Цитата Сообщение от salaga2019 Посмотреть сообщение
раз вы создаете конвертер во View
Конвертер (подобный) - это часть View.
Допустим, вы решили сделать мультиязычный интерфейс.
Переключили локализацию GUI и у вас автоматически будет выдаваться текст на украинском, английском и другом нужном вам языке.
Имеет ли язык интерфейса отношение к логике Модели (Бизнес Логике)?
Определённо нет.
Поэтому и подобный конвертер не имеет отношения к Модели.

НО!
Такой конвертер является универсальным классом.
Ведь никто не может запретить его использовать где угодно, в том числе и в Модели.
Поэтому "по феншую", он должен быть не в самом View, а во внешней Библиотеке.
Можете его переместить в проект Common.
Или создать отдельную библиотеку.

Так же ваши Custom Control (InputTextBoxControl и др.) тоже созданы очень коряво.
Как минимум их надо вынести в отдельной проект "Библиотека для Custom Control WPF" и создавать как полноценные элементы.
Их стили должны быть в теме и подключаться автоматически, как у всех дефолтных элементов.

Цитата Сообщение от salaga2019 Посмотреть сообщение
через 2 часа домой приду внимательно изучу
Ну, как разберёмся с текущим - продолжим дальше.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16444 / 11287 / 2892
Регистрация: 21.04.2018
Сообщений: 33,184
Записей в блоге: 2
10.11.2021, 09:37
salaga2019, добавил в ViewModel связь с Моделью.
Осталось добавить только валидацию в ViewModel.
0
15 / 4 / 2
Регистрация: 16.04.2019
Сообщений: 112
11.11.2021, 05:24  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Ну, как разберёмся с текущим - продолжим дальше.
В целом все понятно, есть несколько моментов:

1. Можете рассказать для чего указывать атрибуты перед классом и когда их нужно применять? Я много видел кода с их использованием, но нигде не описывали зачем они их использовали, у меня есть предположение что это для того, чтобы ограничить класс для работы только с типами данных, указанных в атрибутах, что-то своего рода фильтра, но не уверен.

2. Почему вы используете в разметке FrameworkElement.Resources, а не Window.Resources?

3. Хочу уточнить, чем отличаются эти 4 способа установки DataContext? Я видел у Вас 4 варианта, я не придавал этому особого значения, но увидел, что Вы в разных проектах по разному задаете DataContext, и мне стало интересно, почему.

1) DataContext="{x:Static vm:MainWindowViewModel.DemoInstance}"
2) d : DataContext="{x:Static local:MessagesViewModel.XamlInstace}"

3)
XML
1
2
3
    <Window.DataContext>
        <vm:MainWindowViewModel/>
    </Window.DataContext>
4)
C#
1
2
3
4
5
public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainWindowViewModel();
        }
0
 Аватар для Andrey-MSK
3397 / 2283 / 388
Регистрация: 14.08.2018
Сообщений: 7,770
Записей в блоге: 4
11.11.2021, 06:09
Цитата Сообщение от salaga2019 Посмотреть сообщение
XML
1
d : DataContext="{x:Static local:MessagesViewModel.XamlInstace}"
Скорее всего это контекст времени разработки.
Полная запись вот такая
XML
1
2
        d:DataContext="{d:DesignInstance Type=vmodels:LaborHBSearchWindowVM}"
        mc:Ignorable="d"
0
15 / 4 / 2
Регистрация: 16.04.2019
Сообщений: 112
11.11.2021, 06:26  [ТС]
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Скорее всего это контекст времени разработки.
Полная запись вот такая
XML
1
2
        d:DataContext="{d:DesignInstance Type=vmodels:LaborHBSearchWindowVM}"
        mc:Ignorable="d"
d : DataContext игнорируется при сборке, на сколько мне известно, он нужен только для удобства работы в XAML и не является настоящим. Мне интересно почему DataContext задается по разному, когда в разметке рекомендуют использовать Window.DataContext(именно VS рекомендует) и в чем отличие и как это отразится на результате.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16444 / 11287 / 2892
Регистрация: 21.04.2018
Сообщений: 33,184
Записей в блоге: 2
11.11.2021, 11:52
Цитата Сообщение от salaga2019 Посмотреть сообщение
1. Можете рассказать для чего указывать атрибуты перед классом и когда их нужно применять? Я много видел кода с их использованием, но нигде не описывали зачем они их использовали, у меня есть предположение что это для того, чтобы ограничить класс для работы только с типами данных, указанных в атрибутах, что-то своего рода фильтра, но не уверен.
Рассказать-то могу, вот только не понял что за атрибуты вы имеете ввиду?
Если перед конвертерами и расширение разметки - они используются Дизайнером XAML и облегчают компиляцию XAML.
В целом - это часть метаданных типа, но не часть его кода логики.
Кому надо - тот использует.
В некоторых случаях имеют существенное значение.
Допустим, в Entity Framewor атрибутами сущностей задаётся схема БД.

Цитата Сообщение от salaga2019 Посмотреть сообщение
2. Почему вы используете в разметке FrameworkElement.Resources, а не Window.Resources?
Привычка.
Resources объявлены в базовом FrameworkElement, поэтому подходят для любого UI элемента.
Иногда бывает объявил на одном уровне компоновки, а потом решил перенести на другой.
Если FrameworkElement.Resources, то просто перенёс и всё.
А если с указанием конкретного типа, то придётся потом ещё "руками" править тип.


Цитата Сообщение от salaga2019 Посмотреть сообщение
3. Хочу уточнить, чем отличаются эти 4 способа установки DataContext? Я видел у Вас 4 варианта, я не придавал этому особого значения, но увидел, что Вы в разных проектах по разному задаете DataContext, и мне стало интересно, почему.
1) DataContext="{x:Static vm:MainWindowViewModel.DemoInstance}"
2) d : DataContext="{x:Static local:MessagesViewModel.XamlInstace}"
2 - Контекст данных Времени Разработки. Он не компилируется и не влияет на приложение во время его исполнения. Просто Демо Данные для Дизайнера, чтобы Окно не выглядело пустым.

1 - Контекст Данных Времени Исполнения. Если не задан Контекст данных Времени Разработки, то будет использоваться и во время разработки. Но это часто невозможно. Допустим, реальный контекст получает данные из БД которой не существует во время разработки.

Цитата Сообщение от salaga2019 Посмотреть сообщение
3)
XML
1
2
3
    <Window.DataContext>
        <vm:MainWindowViewModel/>
    </Window.DataContext>
Первое - это было получение значения статического свойства (или поля).
Чтобы его получить - надо на Шарпе объявить это свойство и инициализировать его.

Третье - это создание экземпляра указанного типа. Здесь же в XAML можно указать и начальные значения свойств экземпляра.
Преимущества такого способа - вы можете в XAML менять значения свойств и сразу (без компиляции) видеть как на это реагирует GUI.

Цитата Сообщение от salaga2019 Посмотреть сообщение
4)
C#
1
2
3
4
5
       public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainWindowViewModel();
        }
Это самый плохой способ и его следует избегать.
Code Behind во время разработки не исполняется.
Поэтому Дизайнер XAML не видит такую инициализацию и остаётся "слепым".
Это затрудняет создание привязок и увеличивает вероятность ошибок.

Если инициализация сложная и в XAML её трудно прописать, то лучше использовать Локатор в App.
Или какое-то иное решение позволяющее и осуществить такую инициализацию, и не оставить Дизайнер слепым.

Добавлено через 3 минуты
Цитата Сообщение от salaga2019 Посмотреть сообщение
в разметке рекомендуют использовать Window.DataContext(именно VS рекомендует)
???
Где она рекомендует?

И в любом случаи не стоит относится к Студии, как к всегда правильному советчику.
Самый яркий пример - это наличие панели инструментов UI элементов и возможность их DragAndDrop в разметку Окна.
Кроме проблем - это ничего не даёт.
0
 Аватар для Andrey-MSK
3397 / 2283 / 388
Регистрация: 14.08.2018
Сообщений: 7,770
Записей в блоге: 4
11.11.2021, 13:50
salaga2019,
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Самый яркий пример - это наличие панели инструментов UI элементов и возможность их DragAndDrop в разметку Окна.
Кроме проблем - это ничего не даёт.
Если не знаешь правильного названия элемента и т.д., то можно просто их накидать оттуда в окно, потом убрать Margin и перетащить в нужный элемент грида окна... Но про Margin некоторые иногда забывают, а то и совсем не знают для чего он нужен
1
15 / 4 / 2
Регистрация: 16.04.2019
Сообщений: 112
11.11.2021, 14:05  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Рассказать-то могу, вот только не понял что за атрибуты вы имеете ввиду?
Если перед конвертерами и расширение разметки - они используются Дизайнером XAML и облегчают компиляцию XAML.
В целом - это часть метаданных типа, но не часть его кода логики.
Кому надо - тот использует.
Это вот эта строчка?
C#
1
[ValueConversion(typeof(decimal), typeof(string))]
???
Где она рекомендует?
Не то чтобы прям вылезает постоянно, просто при наведении на три точки под тегом выводит текст, как рекомендацию, скриншот прикрепил.

И в любом случаи не стоит относится к Студии, как к всегда правильному советчику.
Самый яркий пример - это наличие панели инструментов UI элементов и возможность их DragAndDrop в разметку Окна.
Кроме проблем - это ничего не даёт.
На счет этого не знаю, Вам виднее, я недельку так поперетаскивал, когда еще начинал изучать xaml разметку, потом подумал, вот я перетаскиваю, а названия тэгов, свойств, и т.д. не знаю, все визуально через панель настраиваю, надо учиться писать руками.
Миниатюры
Реализация приложения "Калькулятор НДС"  
0
15 / 4 / 2
Регистрация: 16.04.2019
Сообщений: 112
11.11.2021, 14:10  [ТС]
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Если не знаешь правильного названия элемента и т.д., то можно просто их накидать оттуда в окно, потом убрать Margin и перетащить в нужный элемент грида окна... Но про Margin некоторые иногда забывают, а то и совсем не знают для чего он нужен
Можно, но не нужно)
0
 Аватар для Andrey-MSK
3397 / 2283 / 388
Регистрация: 14.08.2018
Сообщений: 7,770
Записей в блоге: 4
11.11.2021, 14:52
salaga2019, По поводу вашего скрина, студия предлагает прописать контекст для времени разработки. Согласитесь и выберите нужную VM из списка.

Добавлено через 2 минуты
Если в VM есть конструктор, который там что-то делает, то студия попытается визуализировать данные полей VM, в простейшем случае будет выводить имена типов полей в элементах окна.
0
15 / 4 / 2
Регистрация: 16.04.2019
Сообщений: 112
11.11.2021, 14:57  [ТС]
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Если в VM есть конструктор, который там что-то делает, то студия попытается визуализировать данные полей VM, в простейшем случае будет выводить имена типов полей в элементах окна.
Да, я когда сайт парсил, проект компилировал и данные сразу в xaml разметку падали и я уже стили писал для оформления контента, очень удобно.
0
 Аватар для Andrey-MSK
3397 / 2283 / 388
Регистрация: 14.08.2018
Сообщений: 7,770
Записей в блоге: 4
11.11.2021, 14:57
Но могут быть и ошибки в дизайнере XAML, из-за того что например данные VM получает в другом потоке или там будет что-то сложное...
Для избежания такого нужно отключить генерацию кода в дизайнере XAML.
Вот эту кнопель вырубить надо
Миниатюры
Реализация приложения "Калькулятор НДС"  
0
15 / 4 / 2
Регистрация: 16.04.2019
Сообщений: 112
11.11.2021, 15:04  [ТС]
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Вот эту кнопель вырубить надо
А что конкретно делает эта кнопка?
0
 Аватар для Andrey-MSK
3397 / 2283 / 388
Регистрация: 14.08.2018
Сообщений: 7,770
Записей в блоге: 4
11.11.2021, 15:32
Цитата Сообщение от salaga2019 Посмотреть сообщение
А что конкретно делает эта кнопка?
Отключает генерацию содержимого полей VM. Если включена, то будет отображать тип поля в элементе управления, или, если есть в VM данные для времени разработки, будет отображать их, если отключена, то элемент будет пустой.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16444 / 11287 / 2892
Регистрация: 21.04.2018
Сообщений: 33,184
Записей в блоге: 2
11.11.2021, 18:06
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Если не знаешь правильного названия элемента и т.д., то можно просто их накидать оттуда в окно...
Согласен.
Это некий костыль для тех кто только перешёл с Форм и кроме ознакомления с набором UI элементов он больше ни на что не пригоден.
Максимум сделать Окно с одной кнопкой выводящей "Hello World!".
После этого об этой панели стоит забыть.


Цитата Сообщение от salaga2019 Посмотреть сообщение
Это вот эта строчка?
Ну, тогда я правильно понял и уже ответил.

Цитата Сообщение от salaga2019 Посмотреть сообщение
Не то чтобы прям вылезает постоянно, просто при наведении на три точки под тегом выводит текст, как рекомендацию, скриншот прикрепил.
А..., понял.
Это когда вы , вообще, контекст данных не задаёте.
Ну, Студия же не знает как вам правильно его нужно создать.
Поэтому если у типа есть конструктор по умолчанию, то предлагает создать экземпляр типа.
Если в приложении одно Окно с постоянным контекстом данных (а большинство приложений именно таких), то это вполне приемлемый вариант.
Но, он не всегда удобен для обращения из элементов у которых контекст данных наследуется не от Окна.
Допустим, чтобы задать команду в элементе ItemsControl придётся уже использовать "танцы с бубном".

Более удобный и тоже простой вариант, но который позволят обращаться к VM с любого уровня иерархии:
XML
1
2
3
4
5
6
<Window -----------
        -----------
        DataContext="{DynamicResource viewModel}">
    <Window.Resources>
        <vms:MainViewModel x:Key="viewModel"/>
    </Window.Resources>
Добавлено через 4 минуты
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Но могут быть и ошибки в дизайнере XAML, из-за того что например данные VM получает в другом потоке или там будет что-то сложное...
Лучше не отключать, а в VM определять Режим Разработки и для него генерировать Демо Данные.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
11.11.2021, 18:06

В чеке ставка НДС 0% в нежно чтобы в чеке писал БЕЗ НДС
Здравствуйте все!!! Конфигурация &quot;Управление торговлей&quot;, редакция 10.3 (10.3.40.1) касса штрих онлайн В чеке ставка НДС 0% в...

Выгрузка в "Возмещение НДС Налогоплательщик 3.0" (пик ндс)
Все привет! Помогите пожалуйста, нужно сделать выгрузку из 1с в пик ндс. где можно найти пример выгружаемого файла. нужен формат файла, а...

Рассчитать сумму НДС, начисленную в бюджет; сумму НДС, принятую к вычету; сумму налога к уплате в бюджет
В первом квартале текущего года ООО «Восход» осуществило следующие операции. 1. Приобрело у ЗАО «Заря» партию сырья на общую сумму 59 000...

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

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Вступаем в новую фазу генерации favicons, векторную.
russiannick 02.11.2026
Теперь нет нужды скрывать что используется простой svg. Исходный код изображения помещаем в поле и жмем кнопку. Исходник преобразуется в вид корректный для помещения в favicon или в url(). Нажатие. . .
Генератор паролей (вариант №4)
Maks 01.11.2026
После публикации 3-го варианта генератора паролей, разослал его своим коллегам (с целью оценки), в итоге были получены следующие рекомендации: 1. Вернуть возможность использования знаков | 1 l I;. . .
Генератор паролей (вариант №3)
Maks 30.10.2026
Финальная версия генератора паролей 1С. Доработка решения в этот раз коснулась только визуальной части, а именно, добавлен реквизит ДопПараметры (тип Булево), который скрывает/ отображает реквизиты:. . .
Магическое мышление и магия, современная наука не отличима от магии (говорит ИИ Джемени)
zorxor 30.10.2026
Джемени, расскажи, пожалуйста, что такое магическое мышление, что такое магия, почему современная наука чем-то напоминает магию? Фраза «Любая достаточно развитая технология неотличима от магии». . .
За какое время ИИ может подобрать пароль по хешу (рассказывает Джемени ИИ)
zorxor 30.10.2026
Расскажи, Джемени, если известен хэш МД5, например, за сколько ИИ сможет подобрать соответствующий пароль? Искусственный интеллект (ИИ) может подобрать простой или средний по сложности пароль по. . .
Кто убил Suno? Почему наше солнышко погасло? (диалог с ИИ Джемени)
zorxor 30.10.2026
Как убивали Suno. Хронология. «Убийство» музыкальной нейросети Suno — это затяжной процесс, в котором технологический хайп стартапа разбился о жесткую реальность судебных исков от гигантов. . .
Генератор паролей (вариант №2)
Maks 30.10.2026
Обновленная версия ранее созданной обработки. Добавлены следующие реквизиты типа Булево: - Буквы; - Цифры; - Символы. Изменена логика команды "Сгенерировать" и процедуры "ПриОткрытии":. . .
Генератор паролей (вариант №1)
Maks 29.10.2026
Реализация из решения ниже выполнена исключительно по моей инициативе, дабы облегчить себе работу в создании паролей для администрируемых мною сервисов и пользователей. Самым главным критерием для. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru