Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.60/25: Рейтинг темы: голосов - 25, средняя оценка - 4.60
8 / 6 / 4
Регистрация: 02.07.2019
Сообщений: 77

Создание нового экземпляра класса, который не известен заранее

05.05.2020, 13:40. Показов 5436. Ответов 34

Студворк — интернет-сервис помощи студентам
Привет! Есть окно добавления нового сотрудника в структуру организации. Сотрудники разделены классами.

Вопрос:
Как создать экземпляр заранее неизвестного класса, когда известен только абстрактный родитель?
Как правильно организовать добавление нового сотрудника, что бы избежать такого количества копипаста?
Похоже не правильно организована структура?(
Проект на ГитХаб

Структура классов такая:
abstract BasePerson
У него 2 потомка
abstract BaseSubordinates (родитель для всех рабочих) : BasePerson
Intern : BaseSubordinates
Worker : BaseSubordinates
abstract BaseDirector (родитель для всех управленцев) : BasePerson
DepartamentHead : BaseDirector
LowDirector : BaseDirector
MidDirector : LowDirector
TopDirector : MidDirector
King : TopDirector

Это основное View диалога добавления
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
98
99
100
101
102
103
<Window x:Class="OrgInfoSystemFW.View.Dialogs.EmloyeeDialog.EmployeeDialogView"
        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:local="clr-namespace:OrgInfoSystemFW.View.Dialogs.EmloyeeDialog"
        mc:Ignorable="d"
        Title="EmployeeDialogView" Height="450" MinWidth="450" Width="450">
    <Window.Resources>
        <!--Дополнительные Контроллы-->
        <!--<local:AddInternControl x:Key="InternControl"/>-->
 
        <!--Стиль кнопок-->
        <Style TargetType="Button">
            <Setter Property="Height" Value="25"/>
            <Setter Property="Width" Value="60"/>
            <Setter Property="Margin" Value="15,10"/>
        </Style>
        <!--Стиль текстблоков-->
        <Style TargetType="TextBlock">
            <Setter Property="VerticalAlignment" Value="Center"/>
            <Setter Property="Margin" Value="30,0"/>
            <Setter Property="FontSize" Value="14"/>
        </Style>
        <!--Стиль текстбоксов-->
        <Style TargetType="TextBox">
            <Setter Property="HorizontalAlignment" Value="Left"/>
            <Setter Property="VerticalAlignment" Value="Center"/>
            <Setter Property="Margin" Value="5"/>
            <Setter Property="MinWidth" Value="200"/>
        </Style>
        <Style TargetType="DatePicker">
            <Setter Property="HorizontalAlignment" Value="Left"/>
            <Setter Property="VerticalAlignment" Value="Center"/>
            <Setter Property="Margin" Value="5"/>
            <Setter Property="MinWidth" Value="200"/>
        </Style>
        <!--Стиль комбобокса-->
        <Style TargetType="ComboBox">
            <Setter Property="HorizontalAlignment" Value="Left"/>
            <Setter Property="VerticalAlignment" Value="Center"/>
            <Setter Property="Margin" Value="5"/>
            <Setter Property="MinWidth" Value="200"/>
        </Style>
        <!--Стиль строк таблицы-->
        <Style TargetType="RowDefinition">
            <Setter Property="Height" Value="40"/>
        </Style>
        <!--Стиль столбца таблицы-->
        <Style TargetType="ColumnDefinition">
            <Setter Property="Width" Value="200"/>
        </Style>
 
    </Window.Resources>
    <DockPanel>
        <!--Кнопки-->
        <StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal"
                    VerticalAlignment="Center" HorizontalAlignment="Center">
            <Button Content="Ок" IsDefault="True" 
                    Height="25" Width="60" Margin="15,10" Click="Button_Click"/>
            <Button Content="Отмена" IsCancel="True"/>
        </StackPanel>
 
        <Grid DockPanel.Dock="Top" VerticalAlignment="Top">
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition Height="auto"/>
            </Grid.RowDefinitions>
 
            <TextBlock  Text="Должность"         Grid.Row="0" Grid.Column="0"/>
            <TextBlock  Text="Имя"               Grid.Row="1" Grid.Column="0"/>
            <TextBlock  Text="Фамилия"           Grid.Row="2" Grid.Column="0"/>
            <TextBlock  Text="Дата рождения"     Grid.Row="3" Grid.Column="0"/>
            <TextBlock  Text="Возраст"           Grid.Row="4" Grid.Column="0"/>
            <TextBlock  Text="Адрес проживания"  Grid.Row="5" Grid.Column="0"/>
            <TextBlock  Text="Специальность"     Grid.Row="6" Grid.Column="0"/>
 
            <ComboBox   x:Name="ClassCB" Grid.Row="0" Grid.Column="1" 
                        ItemsSource="{Binding Classes, XPath=Keys}"
                        SelectedItem="{Binding Path=SelectedClass, Mode=TwoWay}"
                        SelectionChanged="ClassCB_SelectionChanged"/>
            <TextBox    x:Name="NameTB"     Grid.Row="1" Grid.Column="1"/>
            <TextBox    x:Name="SurnameTB"  Grid.Row="2" Grid.Column="1"/>
            <DatePicker x:Name="BirthDayTB" Grid.Row="3" Grid.Column="1"/>
            <TextBox    x:Name="AgeTB"      Grid.Row="4" Grid.Column="1"    IsReadOnly="True"/>
            <TextBox    x:Name="AddressTB"  Grid.Row="5" Grid.Column="1"/>
            <TextBox    x:Name="PositionTB" Grid.Row="6" Grid.Column="1"/>
            <ContentPresenter Grid.Row="8" Grid.Column="0"
                              Grid.ColumnSpan="2"
                              x:Name="contentPresenter"/>
        </Grid>
    </DockPanel>
</Window>
Данный код не работает, потому что по нажатию кнопки нет информации о дополнительных полях.
Но если логику создания нового работника засунуть в обработчик ClassCB_SelectionChanged, то будет создаваться пустой работник(
Это его CB
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
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
using OrgInfoSystemFW.Model.Workers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
 
namespace OrgInfoSystemFW.View.Dialogs.EmloyeeDialog
{
    /// <summary>
    /// Логика взаимодействия для EmployeeDialogView.xaml
    /// </summary>
    public partial class EmployeeDialogView : Window
    {
        Dictionary<string, Type> Classes => BasePerson.Classes;
        public BasePerson person;
        Type SelectedType = null;
 
        public EmployeeDialogView()
        {
            InitializeComponent();
            ClassCB.ItemsSource = Classes.Keys;
        }
 
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            switch (SelectedType.Name)
            {
                case "Intern":
                    InternControl ic = new InternControl();
                    contentPresenter.Content = ic;
                    Intern p = new Intern();
                    p.Name = NameTB.Text;
                    p.Surname = SurnameTB.Text;
                    p.Birthday = BirthDayTB.DisplayDate;
                    p.Address = AddressTB.Text;
                    p.Position = PositionTB.Text;
                    p.Salary = ConvertTbToDouble(ic.SalaryTB.Text);
                    person = p;
                    break;
                case "Worker":
                    WorkerControl wc = new WorkerControl();
                    contentPresenter.Content = wc;
                    Worker w = new Worker();
                    w.Name = NameTB.Text;
                    w.Surname = SurnameTB.Text;
                    w.Birthday = BirthDayTB.DisplayDate;
                    w.Address = AddressTB.Text;
                    w.Position = PositionTB.Text;
                    w.WorkHours = ConvertTbToDouble(wc.workHoursTB.Text);
                    w.Salary = ConvertTbToDouble(wc.SalaryTB.Text);
                    person = w;
                    break;
                default:
                    DirectorControl dc = new DirectorControl();
                    contentPresenter.Content = dc;
                    switch (SelectedType.Name)
                    {
                        case "DepartmentHead":
                            DepartmentHead dh = new DepartmentHead();
                            dh.Name = NameTB.Text;
                            dh.Surname = SurnameTB.Text;
                            dh.Birthday = BirthDayTB.DisplayDate;
                            dh.Address = AddressTB.Text;
                            dh.Position = PositionTB.Text;
                            dh.CoefSalary  = ConvertTbToDouble(dc.coefSalaryTB.Text);
                            dh.LowSalary = ConvertTbToDouble(dc.lowSalaryTB.Text);
                            person = dh;
                            break;
                        case "LowDirector":
                            LowDirector ld = new LowDirector();
                            ld.Name = NameTB.Text;
                            ld.Surname = SurnameTB.Text;
                            ld.Birthday = BirthDayTB.DisplayDate;
                            ld.Address = AddressTB.Text;
                            ld.Position = PositionTB.Text;
                            ld.CoefSalary = ConvertTbToDouble(dc.coefSalaryTB.Text);
                            ld.LowSalary = ConvertTbToDouble(dc.lowSalaryTB.Text);
                            person = ld;
                            break;
                        case "MidDirector":
                            MidDirector md = new MidDirector();
                            md.Name = NameTB.Text;
                            md.Surname = SurnameTB.Text;
                            md.Birthday = BirthDayTB.DisplayDate;
                            md.Address = AddressTB.Text;
                            md.Position = PositionTB.Text;
                            md.CoefSalary = ConvertTbToDouble(dc.coefSalaryTB.Text);
                            md.LowSalary = ConvertTbToDouble(dc.lowSalaryTB.Text);
                            person = md;
                            break;
                        case "TopDirector":
                            TopDirector td = new TopDirector();
                            td.Name = NameTB.Text;
                            td.Surname = SurnameTB.Text;
                            td.Birthday = BirthDayTB.DisplayDate;
                            td.Address = AddressTB.Text;
                            td.Position = PositionTB.Text;
                            td.CoefSalary = ConvertTbToDouble(dc.coefSalaryTB.Text);
                            td.LowSalary = ConvertTbToDouble(dc.lowSalaryTB.Text);
                            person = td;
                            break;
                        case "King":
                            King k = new King();
                            k.Name = NameTB.Text;
                            k.Surname = SurnameTB.Text;
                            k.Birthday = BirthDayTB.DisplayDate;
                            k.Address = AddressTB.Text;
                            k.Position = PositionTB.Text;
                            k.CoefSalary = ConvertTbToDouble(dc.coefSalaryTB.Text);
                            k.LowSalary = ConvertTbToDouble(dc.lowSalaryTB.Text);
                            person = k;
                            break;
                    }
                    break;
            }
            this.DialogResult = true;
        }
 
        private void ClassCB_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            SelectedType = Classes[ClassCB.SelectedValue.ToString()];
        }
 
 
 
        /// <summary>
        /// Возвращает из строки либо дабл, либо ноль
        /// </summary>
        /// <param name="value">Входная строка</param>
        double ConvertTbToDouble (string value)
        {
            double result = double.TryParse(value, out result) ? result : 0;
            return result;
        }
    }
}
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
05.05.2020, 13:40
Ответы с готовыми решениями:

Создание нового экземпляра дочернего класса из экземпляра базового
Всем привет! Извиняюсь, если вопрос глупый, но что-то не смог найти конкретный ответ на него... У меня есть несколько классов: все они...

Создание нового экземпляра класса а позже его удаление
Всем привет. Есть допустим дерево и оно растет. Каждый его блок это экземпляр класса Tree, только я вот не знаю куда оно расти будет. И...

Создание экземпляра класса, разрушение экземпляра класса
Не могу найти информацию про разрущение экземпляра класса. Объясните пожалуйста, что это?

34
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
09.05.2020, 21:34
Студворк — интернет-сервис помощи студентам
Alessey, вариант с лучшим выделением методов Модели.
Вложения
Тип файла: 7z DifferentViewsForTypeHierarchySln(Alessey)1.7z (20.7 Кб, 1 просмотров)
2
8 / 6 / 4
Регистрация: 02.07.2019
Сообщений: 77
10.05.2020, 14:27  [ТС]
Офигеть! Это ж целое приложение!!! Спасибо. буду разбираться и переделывать свое приложение в соответствии с вашим примером. Я тут два дня только логику по департаменту от MV отделял и все равно близко нет к тому что вы сделали!
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
10.05.2020, 16:30
Цитата Сообщение от Alessey Посмотреть сообщение
Я тут два дня только логику по департаменту от MV отделял и все равно близко нет к тому что вы сделали!
Мой совет.
Для нормальной реализации начните не с View, а с БД и Репозитория на Entity Framework.
Репозиторий - для этой задачи нужен из нескольких типов.
У них будет общий Контекст Данных, но внешние интерфейсы будут разные.

Репозиторий с Контекстом данных обменивается данными в типах для EF.
А для внешнего общения у него должны быть неизменяемые DTO типы.

Потом к ним сделайте Модель. Модель должна обмениваться со всеми только в DTO типах.

После занимаетесь View. Для каждого типа View создаёте свой интерфейс через который этот тип может получить всю нужную информацию.
Для удобства Дизайна можете реализовать некоторые из них в виде временных VM предоставляющих Контекст Данных Времени Разработки.

Когда вы завершите View у вас с одной стороны будет готовая Модель с другой готовая View.
И создание VM (тоже скорее всего из нескольких типов) значительно упростится.
Сразу будет понятно откуда брать данные, куда их отправлять, как реагировать на действия в GUI интерфейсе.
0
8 / 6 / 4
Регистрация: 02.07.2019
Сообщений: 77
10.05.2020, 20:48  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Репозиторий - для этой задачи нужен из нескольких типов.
У них будет общий Контекст Данных, но внешние интерфейсы будут разные.
А можно это как то расшифровать? Что значит состоящий из нескольких типов данных? Я так понимаю, репозиторий состоящий из нескольких типов это и есть база данных, которая содержит таблицы для работников, руководителей, департаментов и дополнительные таблицы для связывания таблиц, относящихся к классам. БД будет в следущей задаче. Там какуюто имитацию банка надо делать. Така структура как здесь была выбрана на пробу и похоже это не правильный подход(

Цитата Сообщение от Элд Хасп Посмотреть сообщение
После занимаетесь View. Для каждого типа View создаёте свой интерфейс через который этот тип может получить всю нужную информацию.
Для удобства Дизайна можете реализовать некоторые из них в виде временных VM предоставляющих Контекст Данных Времени Разработки.
А вот это совсем не понятно(( Надеюсь когда-нибудь дойдет. Пробовал я делать как описано на стэковерфлоу, но без понимания принципа действия не смог адаптировать их решенеи под свой проект(
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
10.05.2020, 20:58
Цитата Сообщение от Alessey Посмотреть сообщение
А можно это как то расшифровать? Что значит состоящий из нескольких типов данных? Я так понимаю, репозиторий состоящий из нескольких типов это и есть база данных....
Нет.
БД - это хранилище данных.
А для доступа к нему вы создаёте Контекст БД - производный класс от DbContecxt.
В этом контексте есть свойств для доступа ко всем элементам БД.
Но одновременно вам они все не нужны. И смысла всё это записывать в один тип нет.

Поэтому вы делаете (как пример) репозиторий работающий с персоналом. Он аккумулирует все методы для работы с персоналом: получить персонал по таким то критериям, получить конкретного работника, изменить данные работника, добавить/удалить работника и т.д.
Потом делает второй репозиторий для работы со структурой организации. Здесь методы для работы и изменения структуры.
Третий тип - для получения различных сводных отчётов.
Ну и так далее.

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

И Модели уже за определёнными данными будет обращаться к тому или иному репозиторию.
0
8 / 6 / 4
Регистрация: 02.07.2019
Сообщений: 77
10.05.2020, 21:03  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
БД - это хранилище данных.
А для доступа к нему вы создаёте Контекст БД - производный класс от DbContecxt.
Вот теперь понял) Я думал DbContext это датаконтекст называют и делают один для работы с БД. Спасибо)
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
10.05.2020, 21:17
Цитата Сообщение от Alessey Посмотреть сообщение
Я думал DbContext это датаконтекст называют и делают один для работы с БД.
Его делают один.
И все Репозитории работают с ним одним.
Но только с нужными его частями.
Сам по себе DbContext ничего не занимает и не использует.
Поэтому большое количество его свойств не мешает.
Их заполнение происходит только запроса к значению его свойств.
И заполняются только те свойства которые запрашиваются.

Поэтому один DbContext можно безболезненно разделить между несколькими репозиториями.
0
8 / 6 / 4
Регистрация: 02.07.2019
Сообщений: 77
10.05.2020, 21:36  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Посмотрите приложенный архив.
Будут вопросы - задавайте.
Пытаюсь переделать свой проект в соответствии с вашим решением и понимаю, что ничего не понимаю( С чего начать, каков принцип этого всего((
Повторю этот ваш проект, может чего прояснится)
Пример создания приложения "Работа с комнатами в студенческих общежитиях" [WPF, SQLite, Элд Хасп]
Или можете рекомендовать какой другой пример, где есть объяснения текущих действий?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
10.05.2020, 21:43
Цитата Сообщение от Alessey Посмотреть сообщение
А вот это совсем не понятно(( Надеюсь когда-нибудь дойдет....
Допустим, есть маленький UserControl для вывода статистики
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
<Window 
    x:Name="window"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:common="clr-namespace:Common"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:CF2002"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    xmlns:collections="clr-namespace:System.Collections;assembly=mscorlib"
    xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero2"
    x:Class="CF2002.MainWindow"
    Title="MainWindow"
    mc:Ignorable="d"
    WindowStartupLocation="CenterScreen"
    FontSize="16" 
    SizeToContent="WidthAndHeight"
    >
    <Window.Resources>
        <x:Array x:Key="Images" Type="{x:Type local:ImageData}">
            <local:ImageData Title="Зелённый чай" Image="Resources/Плюс.png"/>
            <local:ImageData Title="Чёрный чай" Image="Resources/Стрелка Вправо.png"/>
            <local:ImageData Title="Красный чай" Image="Resources/Красный крестик.png"/>
        </x:Array>
    </Window.Resources>
    <Grid Width="1000" Height="750">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <ListBox x:Name="listBox" ItemsSource="{Binding Mode=OneWay, Source={StaticResource Images}}" DisplayMemberPath="Title"/>
        <Image Grid.Column="1" Source="{Binding SelectedItem.Image, ElementName=listBox}"/>
    </Grid>
</Window>
Но все его привязки в Режиме Разработки "мёртвые".
То есть Конструктор их не видит, создавать привязки приходится "на глазок" и нет ни какой возможности их проверить.


Чтобы избежать случайных ошибок мы объявляем интерфейс в котором указаны все нужные этому контролу свойства.
C#
1
2
3
4
5
6
7
8
9
10
11
12
namespace Common
{
    public interface IStatisticVM
    {
        /// <summary>Список игроков</summary>
        ObservableCollection<User> Users { get; }
 
        /// <summary>Вернуться на 1ю панель</summary>
        ICommand ShowFirstScreenCommand { get; }
 
    }
}
И указываем в XAML его как источник данных времени Дизайна
XML
6
7
8
9
10
11
             xmlns:local="clr-namespace:View"
             mc:Ignorable="d"
             xmlns:comm="clr-namespace:Common;assembly=Common"
             d:DataContext="{x:Type comm:IStaticticVM}">
    <Grid>
        <Grid.RowDefinitions>
Уже намного удобнее. Свойства уже видны в Конструкторе Привязок, еже можно безошибочно их создавать.
Плюс к этому мы получаем готовое ТЗ на VM - в неё надо только реализовать этот интерфейс и наш UC гарантированно будет с ней работать.


Но касаемо самого создания дизайна, свойства хоть и есть, но они пустые, незаполненные.
И непонятно как будет выглядеть дизайн когда в них будут значения.
Для решения этой проблемы, создаём временную частичную VM предоставляющую данные Времени Конструирования.

Делается она очень просто: объявляется класс производный от интерфейса и нажимается в "Быстрых Решениях" - "Реализовать Интерфейс". Остаётся только заполнить полученную "рыбу" значениями
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
namespace View
{
    public class StatisticVM : IStatisticVM
    {
        public ObservableCollection<User> Users => new ObservableCollection<User> {//удалить?
            new User(){ Name = "Иван", Total=111,  Win=56, Lose=5 },
            new User(){ Name = "Петр", Total=31,  Win=26, Lose=5 },
            new User(){ Name = "Сидор", Total=81,  Win=44, Lose=5 },
            new User(){ Name = "Феофан", Total=1000,  Win=777, Lose=5 },
            new User(){ Name = "Акакий", Total=9999,  Win=56, Lose=888 },
            new User(){ Name = "Ivengo", Total=564,  Win=564, Lose=0 }
        };
 
        public ICommand ShowFirstScreenCommand { get; }
    }
}
Добавляем его в XAML
XML
6
7
8
9
10
11
12
13
             xmlns:local="clr-namespace:View"
             mc:Ignorable="d"
             xmlns:comm="clr-namespace:Common;assembly=Common" Width="350">
    <d:UserControl.DataContext>
        <local:StatisticVM />
    </d:UserControl.DataContext>
    <Grid>
        <Grid.RowDefinitions>
И теперь видим как выглядит наш контрол если его заполнить данными.


Когда подходим к реализации VM, то указываем в ней все требуемые интерфейсы.
Нажимаем на каждом "Реализовать интерфейс" и шаблон уже готов.
C#
1
2
3
4
5
6
7
8
using System.Windows.Media;
 
namespace ViewModel
{
    public class MainViewModel : OnPropertyChangedClass, IGameEndVM, IFirstScreenVM, IGamersVM, IGameVM, ISettingsVM, IStatisticVM, IGameEndDrawVM
    {
        private readonly Action<Type> windowsChanger;
        public MainViewModel(Action<Type> windowsChanger, bool isDisignedMode = true)
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
10.05.2020, 21:46
Цитата Сообщение от Alessey Посмотреть сообщение
Повторю этот ваш проект, может чего прояснится)
Пример создания приложения "Работа с комнатами в студенческих общежитиях" [WPF, SQLite, Элд Хасп]
Или можете рекомендовать какой другой пример, где есть объяснения текущих действий?
Попробуйте.
У него там две версии.
Одна XML, вторая БД SQLite.

Хотел сделать ещё третью улучшенную, но нет времени.
Появится дополню.

Примеров проще есть несколько в подписи моего поста.
Но с БД и выделенным репозиторием только эта.
0
8 / 6 / 4
Регистрация: 02.07.2019
Сообщений: 77
11.05.2020, 20:09  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Чтобы избежать случайных ошибок мы объявляем интерфейс в котором указаны все нужные этому контролу свойства.
Тоесть этот интерфейс мы создаем во время создания View и дополняем его по мере необходимости? Или нужно сразу продумать привязки и создать интерфейс?
0
8 / 6 / 4
Регистрация: 02.07.2019
Сообщений: 77
11.05.2020, 20:49  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Уже намного удобнее. Свойства уже видны в Конструкторе Привязок, еже можно безошибочно их создавать.
Плюс к этому мы получаем готовое ТЗ на VM - в неё надо только реализовать этот интерфейс и наш UC гарантированно будет с ней работать.
Что то с интерфейсом не работает(( Или я куда то не туда нажимаю?
Миниатюры
Создание нового экземпляра класса, который не известен заранее  
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
11.05.2020, 21:05
Цитата Сообщение от Alessey Посмотреть сообщение
Тоесть этот интерфейс мы создаем во время создания View и дополняем его по мере необходимости? Или нужно сразу продумать привязки и создать интерфейс?
Сначала создаётся интерфейс и, если нужно, Контекст Данных Времени Разработки.
Иначе весь смысл их создания (для удобства Разработки Дизайна) теряется.

Но по ходу реализации, конечно, может обнаружится, что что-то упустили или надо изменить.
При необходимости сначала вносятся изменения в интерфейс, потом в Контекст Данных Времени Разработки.
Чтобы сразу было ясно какие есть особенности реализации интерфейса.

Добавлено через 1 минуту
Цитата Сообщение от Alessey Посмотреть сообщение
Что то с интерфейсом не работает(( Или я куда то не туда нажимаю?
А откуда это у вас окошко появилось?

Для вызова Конструктора Привязок надо в окне "Свойства" нажать на маленький квадратик справа от названия и значения нужного свойства.

Добавлено через 10 минут
Так же подсказки появляются при наборе XAML "в ручную".
Появляется всплывающее окошко с подсказками IntelliSense.
Но в XAML они не всегда корректно работают.

Во-первых, Конструктор XAML смотрит C# не в проектах, а в сборках.
Поэтому, если после изменений, не сделать сборку проекта, то изменения Конструктор не увидит.

Во-вторых, изредка тупит в шаблонах и стилях.
Бывает IntelliSense видит, а Конструктор Привязок - нет.
Или наоборот.
1
8 / 6 / 4
Регистрация: 02.07.2019
Сообщений: 77
11.05.2020, 21:19  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Во-вторых, изредка тупит в шаблонах и стилях.
Бывает IntelliSense видит, а Конструктор Привязок - нет.
Или наоборот.
Да. В конструкторе видно, в коде нет, сборку делал. Я думал это будет как с использованием файла класса VM, т.е. будет в коде предлагаться в любом месте проекта... И похоже, что привязка события формы KeyUp="{Binding KeyUpCommand}" работать не будет и придется делать в КодБихаенд?
А что означает Run перед тегом XAML? Оно объединяет одинаковые теги <Text> в одну строку?
Миниатюры
Создание нового экземпляра класса, который не известен заранее  
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
11.05.2020, 22:13
Цитата Сообщение от Alessey Посмотреть сообщение
И похоже, что привязка события формы KeyUp="{Binding KeyUpCommand}" работать не будет и придется делать в КодБихаенд?
KeyUp - это событие, а не свойство.
Ему надо указать обработчик события (метод с соответствующей сигнатурой).
Привязку можно задать к команде.
Почитайте:
InputBindings
KeyBinding
MouseBinding

Добавлено через 21 минуту
Цитата Сообщение от Alessey Посмотреть сообщение
А что означает Run перед тегом XAML? Оно объединяет одинаковые теги <Text> в одну строку?
TextBlock - может содержать не только простой текст: <Run/>, <LineBreak/>, <Hyperlink/>.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
11.05.2020, 22:13

Получить константу из экземпляра класса, который является членом другого класса
class test { const STATUS = 1; } $a = new test(); echo $a::STATUS . PHP_EOL; // работает class bar {

Создание экземпляра класса-наследника для переменной с типом базового класса
Подскажите чайнику как создается экземпляр класса BC BaseClass BC = new DerivedClass(); Вопрос: BC - это экземпляр класса BaseClass...

Создание экземпляра класса, имя класса находиться в строковой переменной
Подскажите люди добрые, как можно выйти из такой ситуации, вот допустим имеются классы class new1{ . . . } class new2{ . . ...

Явное создание экземпляра класса и явная специализация шаблона класса
Всем добрый день! Не могу разобраться - эти две технологии дают один и тот же результат? В каких случаях применять одно и другое?...

Пример класса с конструктором и деструктором, создание экземпляра класса через конструктор с параметрами
Привести пример класса с конструктором и деструктором, созданием экземпляра класса с помощью конструктора с параметрами.


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

Или воспользуйтесь поиском по форуму:
35
Ответ Создать тему
Новые блоги и статьи
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru