Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.89/18: Рейтинг темы: голосов - 18, средняя оценка - 4.89
1 / 1 / 0
Регистрация: 27.01.2016
Сообщений: 20
UWP

MVVM Привязка событий к кнопке

21.09.2021, 14:17. Показов 4432. Ответов 36
Метки mvvm, uwp (Все метки)

Студворк — интернет-сервис помощи студентам
Начал изучать uwp и mvvm. Создал приложение, добавил кнопу на View и связал ее с методом Button_click в viewModel

Объявление Button во view


XML
1
     <Button Content="My App"   Height="122" Width="418" Click="{x:Bind viewmodel:CustomersViewModel.Button_Click}"  Margin="417,129,0,0" VerticalAlignment="Top"/>
Объявление DataContext

C#
1
 DataContext = new CustomersViewModel();
Метод Button_Click()

C#
1
2
3
4
5
6
7
8
public static async void Button_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
            {
                MediaElement mediaElement = new MediaElement();
                var synth = new Windows.Media.SpeechSynthesis.SpeechSynthesizer();
                Windows.Media.SpeechSynthesis.SpeechSynthesisStream stream = await synth.SynthesizeTextToStreamAsync("Hello world");
                mediaElement.SetSource(stream, stream.ContentType);
                mediaElement.Play();
            }
Если я привязываю так кнопку, то я могу обратиться только к статическому методу.
XML
1
x:Bind viewmodel:CustomersViewModel.Button_Click
Как обратиться к нестатическому методу? И подскажите как правильно привязывать обработчики событий к кнопке в mvvm (и передавать параметры туда)?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
21.09.2021, 14:17
Ответы с готовыми решениями:

Привязка в MVVM
Здравствуйте! В очередной раз решил познать не самый легкий для меня паттерн. Нашёл неплохой и вроде бы понятный пример, в итоге построив...

MVVM паттерн и привязка данных
Доброго времени суток! Относительно недавно начал изучать данный паттерн и технологию в целом. Не могу привязать данные к datagrid ...

MVVM и DataTable. Привязка к данным
Здравствуйте. Подскажите, пожалуйста. Пробую создать программу с WPF и MVVM. Производя привязку объекта класса DataTable к DataGrid...

36
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
22.11.2022, 13:51
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Vanka03 Посмотреть сообщение
модель - это
Модель - это описание всей бизнес-логики предметной области. Модель не включает в себя ничего из View, ViewModel, хранилища (EF, база, файлы), т.е. модель самодостаточна вообще без каких-либо View+VM (и прочих вышестоящих слоёв). В т.ч. модель (при определённых подходах) может быть полностью самодостаточна без хранилища (базы данных), и даже без абстракции от него.

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

Добавлено через 2 минуты
И из этого всего следует, что правильно реализованный слой модели приложения, может быть легко переиспользован в любом окружении вообще без каких-либо модификаций модели, т.е. одну и ту же модель (dotnet-сборку) можно использовать:
1. В консольном приложении, которое хранит данные модели в JSON-файлах.
2. В WPF-приложении, которое хранит данные в базе данных.
3. В WEB-приложении, которое хранит данные модели где-нибудь в облаке.
1
4 / 4 / 0
Регистрация: 01.11.2013
Сообщений: 216
22.11.2022, 13:53
Цитата Сообщение от kotelok Посмотреть сообщение
Нет:
Есть еще такой вопрос:
В Вашем примере экземпляр VM получает объект модели в контруктор, а кто этот объект модели создает и передает при создании экземпляра VM?
0
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
22.11.2022, 13:58
Цитата Сообщение от Vanka03 Посмотреть сообщение
В Вашем примере экземпляр VM получает объект модели в контруктор, а кто этот объект модели создает и передает при создании экземпляра VM?
Если VM создаётся в реальном приложении, то обычно этим занимается DI-контейнер. Его надо настроить при старте приложения, а дальше он уже сам будет разрешать любые зависимости. Но можно и по-старинке, вручную создавать (но не нужно).

Если экземпляр VM создаётся для тестирования, то там все зависимости можно и вручную создать, или же заглушки для них. Но для это нужно зависимости абстрагировать через интерфейс:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public sealed class SomeModel : ISomeModel
{
    ....
}
 
....
 
public sealed class SomeViewModel
{
    public SomeViewModel(ISomeModel someModel)
    {
         ....
    }
}
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
22.11.2022, 14:10
Vanka03, и вот Окна:
C#
10
11
12
13
14
15
16
    public partial class AddPersonWindow : Window, IClose
    {
        public AddPersonWindow()
        {
            InitializeComponent();
        }
    }
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
<Window x:Class="Core2022.Vanka03.AddPersonWindow"
        x:Name="PART_Main"
        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:Core2022.Vanka03"
        mc:Ignorable="d"
        Title="AddPersonWindow" Height="100" Width="200">
    <d:Window.DataContext>
        <local:PersonsModelViewModel/>
    </d:Window.DataContext>
    <Window.Resources>
        <local:Person x:Key="editablePerson" FirstName="Петя" LastName="Сидоров"/>
        <local:AddPersonArgs x:Key="addArgs"
                             Person="{StaticResource editablePerson}"
                             Close="{x:Reference PART_Main}"/>
    </Window.Resources>
    <UniformGrid Columns="1">
        <TextBox Text="{Binding FirstName, Source={StaticResource editablePerson}}"/>
        <TextBox Text="{Binding LastName, Source={StaticResource editablePerson}}"/>
        <Button Content="Добавить"
                Command="{Binding AddPersonCommand}"
                CommandParameter="{DynamicResource addArgs}"/>
    </UniformGrid>
</Window>
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
<Window x:Class="Core2022.Vanka03.PeopleWindow"
        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:Core2022.Vanka03"
        mc:Ignorable="d"
        Title="PeopleWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:PersonsModelViewModel/>
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <ListBox ItemsSource="{Binding People}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock>
                        <TextBlock.Text>
                            <MultiBinding StringFormat="{}{0} {1}">
                                <Binding Path="FirstName"/>
                                <Binding Path="LastName"/>
                            </MultiBinding>
                        </TextBlock.Text>
                    </TextBlock>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <Button Grid.Row="1" Content="Добавить"
                Click="OnAddPerson"/>
    </Grid>
    <x:Code>
        <![CDATA[
        private void OnAddPerson(object sender, RoutedEventArgs e)
        {
            new AddPersonWindow() { DataContext = DataContext }.ShowDialog();
        }
        ]]>
    </x:Code>
</Window>
Добавлено через 1 минуту
Цитата Сообщение от Vanka03 Посмотреть сообщение
В роли модели в этом конкретном примере выступает класс Person?
Нет. Это просто Сущность, даже ещё проще - DTO.

Модель реализована совместно с VM в одном классе PersonsModelViewModel.

Добавлено через 1 минуту
Цитата Сообщение от Vanka03 Посмотреть сообщение
польщен, что пространство имен названо в мою честь)
Это решение для помощи на Форуме.
Разбито на папки по именам пользователей для кого создаются примеры.

Добавлено через 2 минуты
Как видите - диалог ввода данных создаётся чисто в View.
А добавление по этим данным нового пользователя выполняет уже команда VM.
В каждом новом диалоге автоматически в XAML создаётся новый Person для ввода данных.
Если он не будет добавлен, то просто улетит в мусор.
Если будет - то в коллекцию Людей и автоматически будет отображён в основном Окне.
0
4 / 4 / 0
Регистрация: 01.11.2013
Сообщений: 216
22.11.2022, 14:20
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Vanka03, и вот Окна:
Большое спасибо! Этого примера более, чем достаточно, но хочу уточнить:
Получется, что данные для отображения хранит VM, а не модель? Ведь коллекция People - свойство VM?

Добавлено через 1 минуту
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Разбито на папки по именам пользователей для кого создаются примеры.
Да я понял, шутка такая)

Добавлено через 6 минут
Получается, что модель - это коллекция Person, а команда уже относится к VM? Или тут так сходу не разделить?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
22.11.2022, 14:28
Цитата Сообщение от Vanka03 Посмотреть сообщение
Получается, что данные для отображения хранит VM, а не модель? Ведь коллекция People - свойство VM?
В данном случае это одно и тоже.

При раздельной реализации в Модели будет метод или команда для добавления.
И событие если был добавлен, удалён, изменён Person.
VM вызывает метод Модели.
Передаёт ему данные.
Модель обрабатывает данные, добавляет Person в свою логику.
Если удачно, то метод возвращает true и VM закрывает диалог.
НО!
VM добавляет в свою коллекцию Person только по событию Модели, а не в результате работы метода.

Добавлено через 2 минуты
Цитата Сообщение от Vanka03 Посмотреть сообщение
Или тут так сходу не разделить?
Не разделить.
Для разделения нужно сначала решить когда должен быть закрыт диалог добавления.
Метод добавления в Модели, в общем случае, может выполняться очень долго.
Например, будет запрос на какой-то Web сервер.

Как быть с диалогом?
Передать параметры и сразу закрыть?
Или заморозить в ожидании результата выполнения метода?

Добавлено через 3 минуты
Цитата Сообщение от Vanka03 Посмотреть сообщение
Этого примера более, чем достаточно,
Сразу предупреждаю, что это тоже "поделка на коленке" для обучающих, учебных целей.
В реальных ("взрослых") приложениях используются внедрения зависимостей, сервисы и прочее.
0
4 / 4 / 0
Регистрация: 01.11.2013
Сообщений: 216
22.11.2022, 14:53
Цитата Сообщение от Элд Хасп Посмотреть сообщение
VM добавляет в свою коллекцию Person только по событию Модели, а не в результате работы метода.
Т.е., получается, что при раздельной реализации VM будет хранить коллекцию Person, а в Модели будет
Цитата Сообщение от Элд Хасп Посмотреть сообщение
метод или команда для добавления.
И событие если был добавлен, удалён, изменён Person.
? Т.е., Модель будет чем-то вроде усовершенствованного DTO?

Добавлено через 24 минуты
Цитата Сообщение от Vanka03 Посмотреть сообщение
VM будет хранить коллекцию Person,
Нет, мне кажется, что коллекция People также относится к модели.
0
 Аватар для limeniye
1182 / 624 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
22.11.2022, 14:54
Vanka03, ViewModel -- отображает состояние Model.

Цитата Сообщение от Vanka03 Посмотреть сообщение
Т.е., Модель будет чем-то вроде усовершенствованного DTO?
Нет. Model -- єто не Data-контейнер. Єто слой паттерна MVVM. Не нужно путать.

Model -- єто какой-то сервис, которьій вообще не зависит от WPF. Он может использоваться как в консольном проекте, так и в любом другом.

View "слушает" ViewModel с помощью реализации INotifyPropertyChanged интерфейса, а именно через собьітие PropertyChanged.

ViewModel -- єто слой MVVM паттерна, главной целью которого является оповещение View об изменениях в Model.

А теперь логический вопрос: а откуда ViewModel знает об каких-то изменениях в Model?
Не будете же Вьі запускаскать бесконечньій цикл, которьій будет постоянно проверять: а не изменилась ли коллекция в Model слое?! -- нет, Вьі просто подпишитесь на собьітие изменения и будете его поднимать тогда, когда коллекция в моделе изменилась:

Уровен Model
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class StudentsService
{
    public List<Strudent> Students { get; } = new List<Student>();
    public event Action<Student> StudentsChanged;
    
    public void AddNewStudentToDataBaseTestMethodForDemonstationMVVMPattern(Student newStudent)
    {
        bool isAdded = _db.TryAdd(newStudent); // Сохраняем в БД
 
        if(isAdded)
        {
            Students.Add(newStudent); // Сохраняем локально
            StudentsChanged?.Invoke(newStudent);
        }
    }
}
Уровень ViewModel
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
class StudentsViewModel
{
    public ObservableCollection<Student> Students { get; }
 
    public StudentsViewModel(StudentsService service)
    {
         Students = new ObservableCollection<Student>(service.Students);
         service.StudentsChanged += (e) =>
         { 
              Students.Add(e); 
         };
    }
}
И тут Вьі, возможно, зададитесь вопросом: а не проще ли просто сразу сделать ObservableCollection и не устраивать єти танцьі с бубном вокруг костра?

Проще!
Но внимательно читайте вот єтот вот участок реплики:
Model -- єто какой-то сервис, которьій вообще не зависит от WPF. Он может использоваться как в консольном проекте, так и в любом другом.
Суть в том, что в таком случае мьі абстрагируемся от фреймворка, на котором пишем.
Єто лишь архитектурньій подход, чтобьі у Вас View и Model бьіли независимьіми и Model ни про какие ObservableCollection'ьі не знала в принципе, так как єто ее не касается.
2
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
22.11.2022, 14:56
Цитата Сообщение от Vanka03 Посмотреть сообщение
при раздельной реализации VM будет хранить коллекцию Person, а в Модели будет
В модели будет своя инкапсулированная Бизнес Логика.
Person - это DTO для обмена данными.
В Модели будут свои внутренние Бизнес Сущности, которые отражаются (в том числе) с помощью Person.

Пример слишком просто для объяснения.

Усложним немного.

Есть некая Игра.
У игры есть данные которые нужно сохранять между сеансами.
Этим занимается Репозиторий.
Репозиторий это тоже часть БЛ и Модели.
Но из-за частого использования, о нём часто говорят как об отдельном слое лежащим ниже Модели.
В репозитории для работы с Хранилищем используются какие-то сущности. Например UnityEntity. И эти сущности инкапсулированы в Репозитории поскольку зависимы от Хранилища.

Но только сохранения для логики Игры мало.
Сущности в ней взаимодействую друг с другом, в них есть своя логика.
Поэтому здесь появляется UnityDomain. Обмен данных с Репозиторием в Модели может происходить по разным сценариям.
Предпочитаемая реализация это "Дружественный Репозиторий". В этом случае в Репозиторий поступают UnityDomain.
Если это "Недружественный" репозиторий, то для обмена с ним вводятся ещё UnityDto.

Далее.
Модель должна ещё как-то общаться с потребителями данных.
Отдавать UnityDomain она им не может, так как потребители это всегда "недружественные" объекты. Например, игрок хочет сжульничать и через связанную сущность может повилять на БЛ игры.
Здесь тоже используются DTO. Могут быть те же, что с репозиторием, но могут быть и иные, так как возможно в них нужна интеграция от других сущностей. В том числе это могут быть и "маленькие модельки", которые позволяют с собой безопасно работать.
В результате получим или UnityModel или UnityModelDto.

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

Приходим на уровень View.
А здесь нам понадобились привязки, триггера, шаблоны данных и прочее.
И создаём UnityControl.

Итого получаем цепочку типов: Entity, Dto, Domain, ModelDto, ViewModel, Control.

Это, конечно, сценарий "для страшного сна", но для примера максимальной абстракции, думаю, пойдёт.

Добавлено через 1 минуту
Цитата Сообщение от Vanka03 Посмотреть сообщение
Нет, мне кажется, что коллекция People также относится к модели.
Она может быть в Модели или не быть - это не важно. Это "личное" дело Модели и инкапсулировано в ней.
А вот в VM она должна быть обязательно.
Как без этого View сможет её отобразить?
1
4 / 4 / 0
Регистрация: 01.11.2013
Сообщений: 216
22.11.2022, 15:11
Цитата Сообщение от Элд Хасп Посмотреть сообщение
В модели будет своя инкапсулированная Бизнес Логика.
У меня в голове откуда-то было представление (довольно твердое), что модель - это просто объекты (то, что вы называете DTO, вот так же я представлял себе модель), потребовалось 16 часов и усилия 4х человек для того, что бы понять, что модель это, как Вы сказали, весь слой бизнес-логики, содержайщий всё, кроме взаимодействия с View.
Почему-то я думал, что бизнес-логика должна быть в VM, но теперь с этим покончено, впереди Новая Прекрасная Жизнь (я надеюсь).

Это не означает, что я все понял, и вопросы закончены, но их качество должно повыситься)

Добавлено через 2 минуты
Цитата Сообщение от Элд Хасп Посмотреть сообщение
А вот в VM она должна быть обязательно.
Как без этого View сможет её отобразить?
А разве не может она (VM) обратиться к ней (коллекции) как к полю модели? Ведь есть же у VM экземпляр модели (как в примере kotelok в сообщении 14)? Понял, она должна как минимум переложить ее в свою свойство-коллекцию, чтобы view могла получить ее.

Добавлено через 43 секунды
Цитата Сообщение от limeniye Посмотреть сообщение
Нет. Model -- єто не Data-контейнер. Єто слой паттерна MVVM. Не нужно путать.
Model -- єто какой-то сервис, которьій вообще не зависит от WPF. Он может использоваться как в консольном проекте, так и в любом другом.
Спасибо, с пониманием этого у меня почему-то были большие проблемы.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
22.11.2022, 15:24
Цитата Сообщение от Vanka03 Посмотреть сообщение
А рзаве не модет она обратиться к ней как к полю модели?
Может.
Но подумайте сколько лишних телодвижений придётся для этого сделать.

Person в Модели как-то связан с БЛ.
Например, рассчитывается сколько им еды нужно или фонд зарплаты.
Они могу порождать какие-то другие объекты. Результаты труда например.

А вы взяли просто "лёгким движением" добавили (родили) или удалили (убили) Person в коллекции и Модель даже не узнала об этом.

По факту есть два сценария для БЛ:
1) Коллекция в Модели инкапсулирована (или её вовсе нет). Добавление удаление объектов происходит только через методы Модели, в которые являются частью БЛ. При изменениях коллекции Модель сообщает об этом через своё событие - это, как минимум, нужно чтобы у разных потребителей (VM) были одни и те же данные.

2) Коллекция публичная. Чтобы следить за её состоянием и состоянием сущностей в ней в Модели нужна подписка не только на изменение коллекции, но и на изменении каждой сущности коллекции. При этом для сущностей нужна ещё автоматическая отписка на случай удаления из коллекции. Эта прослушка будет вызвать нужные методы Модели для внесения согласованных изменений в БЛ.

Что проще реализовать?
Думаю первое.
Второе тоже используется, но гораздо реже, в достаточно сложных решениях. Где в коллекции не просто DTO-шки, а Модельки. Когда таких коллекций много и можно сделать одну обобщённую реализацию и использовать её для разных типов.
0
 Аватар для Andrey-MSK
3397 / 2283 / 388
Регистрация: 14.08.2018
Сообщений: 7,758
Записей в блоге: 4
22.11.2022, 15:25
Цитата Сообщение от Vanka03 Посмотреть сообщение
что модель - это просто объекты
В приложениях с работой с СУБД моделью является сама СУБД, а классы, которые представляют таблицы и запросы, это просто DTO. Слой DataAccess в таких приложениях - может быть как частью модели так и частью VM.
1
4 / 4 / 0
Регистрация: 01.11.2013
Сообщений: 216
22.11.2022, 16:30
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Vanka03, вот пример реализации VM и команды в ней:
Прошу прощения, а в Вашем примере из сообщения 17 откуда берется метод GetCommand()? Здесь не нашел Библиотека элементов для реализации WPF MVVM Решений [WPF, Элд Хасп]
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
22.11.2022, 17:31
Цитата Сообщение от Vanka03 Посмотреть сообщение
откуда берется метод GetCommand()? Здесь не нашел Библиотека элементов для реализации WPF MVVM Решений [WPF, Элд Хасп]
Это часть моей реализации базовой VM.
Замените на new RelayCommand<T> из указанной вами ссылки.

Добавлено через 5 минут
Там же по ссылке есть пример как создавать команду.
0
4 / 4 / 0
Регистрация: 01.11.2013
Сообщений: 216
22.11.2022, 17:44
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Замените на new RelayCommand<T> из указанной вами ссылки.
Хорошо, спасибо.

Я немного поразмыслил, хочу еще позадавать вопросы:
У меня есть БД, где есть Дивизионы, Команды и Игроки.
DbContext у меня будет играть роль модели.
На главном окне (Окно1) у меня будет TreeView, где будет информация об них.
У Окна1 есть VM, которая занимается отображением содержимого DbContext на TreeView.
Также на Окне1 есть кнопка "Создать Дивизион". По нажатию на нее открывается окно создания дивизиона (Окно2).
На Окне2 текстовые поля для данных и кнопка "Ок". На Ок я собрался прибиндить команду. Но команда должна формировать объект и отправлять его в DbContext, о котором VM Окна2 пока ничего не знает. Могу ли я, например, создать синглтон для DbContext и обращаться к нему из VM Окна2? Как-то надо же его передать.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
22.11.2022, 17:59
Цитата Сообщение от Vanka03 Посмотреть сообщение
DbContext у меня будет играть роль модели.
Это допустимо, если вы строите GUI для БД.
То есть никакой Бизнес Логики, кроме работы с БД, в вашем приложении нет.
0
4 / 4 / 0
Регистрация: 01.11.2013
Сообщений: 216
22.11.2022, 20:02
Цитата Сообщение от Элд Хасп Посмотреть сообщение
То есть никакой Бизнес Логики, кроме работы с БД, в вашем приложении нет.
Нет, в текущем приложении нет.
А если бы была? Нужно было бы создавать Модель-прослойку, некоторые методы которой отвечали бы за взаимодействие с DbContext?

Добавлено через 2 часа 0 минут
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Vanka03, и вот Окна:
Я был вынужден немного упростить Ваш код, и скрестить его с метанитотм чуть-чуть. Вот что у меня получилось:

VM Окна2:
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
    public class CreateCompanyWindowVm : ViewModelBase
    {
        private string name;
        private string date;
        private string adress;
 
        public CompaniesContext Context { get; set; }
        public AutoCommand AddCompanyCommand =>
            new AutoCommand(obj => { AddCompanyExecute(); });
 
        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
                OnPropertyChanged("Name");
            }
        }
        public string Date
        {
            get
            {
                return date;
            }
            set
            {
                date = value;
                OnPropertyChanged("Date");
            }
        }
 
        public string Adress
        {
            get
            {
                return adress;
            }
            set
            {
                adress = value;
                OnPropertyChanged("Adress");
            }
        }
 
        public CreateCompanyWindowVm()
        {
            Context = new CompaniesContext();
        }
 
        private bool AddCompanyCanExecute()
        {
            return string.IsNullOrWhiteSpace(Name);
        }
 
        private void AddCompanyExecute()
        {
            Company newCompany = new Company()
            {
                Name = this.Name,
                Date = this.Date,
                Adress = this.Adress
            };
 
            Context.Companies.Add(newCompany);
            Context.SaveChanges();
        }
 
    }
AutoCommand(RelayCommand):
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
    public class AutoCommand : ICommand
    {
        private Action<object> execute;
        private Func<object, bool> canExecute;
 
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
 
        public AutoCommand(Action<object> execute, Func<object, bool> canExecute = null)
        {
            this.execute = execute;
            this.canExecute = canExecute;
        }
 
        public bool CanExecute(object parameter)
        {
            return this.canExecute == null || this.canExecute(parameter);
        }
 
        public void Execute(object parameter)
        {
            this.execute(parameter);
        }
    }
Разметка Окна2:
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
<Window x:Class="Companies.CreateCompanyWindow"
        x:Name="PART_Main"
        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:vms="clr-namespace:Companies.VMs"
        mc:Ignorable="d"
        Title="CreateCompanyWindow" Height="270" Width="480">
    <Window.DataContext>
        <vms:CreateCompanyWindowVm/>
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid Grid.ColumnSpan="2" Grid.Row="0">
            <Label Content="Name:" HorizontalAlignment="Left" Margin="32,0,0,0" VerticalAlignment="Center"/>
            <TextBox HorizontalAlignment="Left" Margin="81,0,0,0" TextWrapping="Wrap" VerticalAlignment="Center" Width="360" Text="{Binding Name}"/>
        </Grid>
        <Grid Grid.ColumnSpan="2" Grid.Row="1">
            <Label Content="Date:" HorizontalAlignment="Left" Margin="32,0,0,0" VerticalAlignment="Center"/>
            <TextBox HorizontalAlignment="Left" Margin="81,0,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Center" Width="360"/>
        </Grid>
        <Grid Grid.ColumnSpan="2" Grid.Row="2">
            <Label Content="Adress:" HorizontalAlignment="Left" Margin="32,0,0,0" VerticalAlignment="Center"/>
            <TextBox HorizontalAlignment="Left" Margin="81,0,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Center" Width="360"/>
        </Grid>
        <Button Command="{Binding AddCompanyCommand}" Content="Create" HorizontalAlignment="Center" Grid.Row="3" VerticalAlignment="Top" Height="50" Width="160"/>
        <Button Content="Cancel" HorizontalAlignment="Center" Grid.Row="3" VerticalAlignment="Top" Height="50" Width="160" Grid.Column="1"/>
 
    </Grid>
</Window>
Худо-бедно, но работает, я смог ввести имя компании, и по нажатию на кнопку она попала в БД)

Есть вопросы:
1. У Вас в примере идет привязка текстбоксов к ресурсам, т.е., насколько я понял, при изменении значений в текстбоксах ресурсы не меняются, т.е. в коллекцию People всегда попадает Петя Сидоров? Я решил отказаться от ресурсов вообще, забиндил свои текствоксы к свойствам VM и создаю объект через них. Подскажите, чем мне грозит такой подход?
2. Т.к. я не использую ресурсы решил не использовать обобщенный AutoCommand. Пытался написать так:
C#
1
2
 public AutoCommand AddCompanyCommand =>
            new AutoCommand(obj => { AddCompanyExecute(); }, (obj) => { AddCompanyCanExecute(); });
компиллятор сказал, что не все части кода второй лямбды возвращают значение. Не понял, почему так?
3. При попытке использовать ресурсы в строке
XML
1
 Close="{x:Reference PART_Main}"/>
Получил ошибку:
Error XDG0010 Object of type 'System.Windows.Markup.Reference' cannot be converted to type 'Companies.VMs.IClose'. Вроде имя вверху разметки добавил это, что пошло не так?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
22.11.2022, 20:02

MVVM и обработчик событий
Доброго времени суток. Столкнулся с проблемой. Вот код: Есть обработчик событий DataReceivedHandler, который считывает входящие...

Привязка курса валют к TextBox по MVVM
Здравствуйте! Дайте пошаговое напутствие, как реализовать этот кусок кода в MVVM. Я так понимаю нужно &quot;забиндить&quot; нужный...

Привязка данных без использования паттерна MVVM
Здраствуйте, интересует вопрос как сделать такую привязку. Имеется класс Game.cs: class Game: DependencyObject { ...

WPF MVVM datagrid привязка к разным моделям
Суть такова, хочу сделать чтоб по выбору в комбобокс датагриду присваивались разные модели ? возможно ли это если учесть что в xaml...

MVVM зум объекта, привязка события к кнопке
Добрый день. Для масштабирования исопльзуется такой класс. public class CanvasMouseWheel : Behavior&lt;UIElement&gt; { ...


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

Или воспользуйтесь поиском по форуму:
37
Ответ Создать тему
Новые блоги и статьи
Nekobox - outbounds[0].transport: unknown transport type: raw
damix 01.10.2026
Фикс ошибки Правым кликом по серверу -> отладочная информация -> edit Заменить "net": "raw", на "net": "tcp", Нажать кнопку reload.
Программный домашний кинотеатр
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 и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru