0 / 0 / 0
Регистрация: 17.03.2019
Сообщений: 9
1
UWP

Программное создание элемента XAML UWP MVVM

17.03.2019, 10:15. Показов 5260. Ответов 4

Author24 — интернет-сервис помощи студентам
До недавнего времени я думал, что умею пользоваться поиском. Однако ничего даже близко похожего я не нашел, поэтому и решил написать на форум. Очень нужна ваша помощь!

Программное создание элемента XAML в UWP:

C#
1
2
            Button btn = new Button();
            Panel.Children.Add(btn);
Что делать в случае MVVM? Куда это писать, как получить Panel, если из других классов к нему нет доступа? Почему во всем могучем интернете нет нормального примера создания элемента в рамках паттерна MVVM? Не просто записать какие-то данные в готовые элементы, а сначала создать этот элемент, затем дать пользователю возможность записать туда какие-то данные.
Убедительная просьба расписать все очень и очень доходчиво. Что-то типа: "Тебе нужно создать свойство элемента в модели, затем это свойство передать команде, которая обработает... бла-бла-бла" Для новичка это пустой звук, если вы реально решили помочь, то, пожалуйста, объясните нормально, с кодом, с различными элементами.

Мне нужно программно создать элемент XAML в UWP, затем использовать его. Например, создать панель, задать ей определенный стиль, размеры. Внутрь этой панели поместить текстблок, текстбокс, несколько кнопок. И все это чтобы создавалось по нажатию кнопки внутри основного грида на главной странице.

Без MVVM это могло бы выглядеть так:

XML
1
2
3
4
5
6
    <StackPanel x:Name="Panel">
        <Button x:Name="AddBtn"
        Content="Add Panel"
        Click="AddBtn_Click"
        Margin="10"/>
    </StackPanel>
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
public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }
 
        private void AddBtn_Click(object sender, RoutedEventArgs e)
        {
            StackPanel stackPanel = new StackPanel
            {
                Background = new SolidColorBrush(Colors.Red),
                Margin = new Thickness(10),
                Width = 350,
                Height = 250,
            };
            Panel.Children.Add(stackPanel);
 
            TextBlock header = new TextBlock
            {
                Margin = new Thickness(10),
                Text = "Header",
                Name = "XHeader",
                FontSize = 20,
            };
            stackPanel.Children.Add(header);
 
            TextBox text = new TextBox
            {
                PlaceholderText = "Write text here",
                Margin = new Thickness(10),
                TextWrapping = TextWrapping.Wrap,
                HorizontalAlignment = HorizontalAlignment.Stretch,
            };
            stackPanel.Children.Add(text);
 
            Button btnSave = new Button
            {
                Margin = new Thickness(10),
                HorizontalAlignment = HorizontalAlignment.Right,
                Content = "Save",
            };
            stackPanel.Children.Add(btnSave);
        }
    }
Как быть с MVVM? И просьба не забывать, что это UWP. Всем спасибо за помощь!
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.03.2019, 10:15
Ответы с готовыми решениями:

UWP Xaml MvvmCross MVVM модель
Господа, помогите пожалуйста. UWP проект. Библиотека MvvmCross. Я не понимаю, что-то самое...

Программное создание Line по XAML шаблону
Люди помогите мне сделать line по XAML шаблону* при нажатии на button. Вот шаблон линии которая...

[UWP] Статический ресурс XAML
Добрый день! Есть класс: namespace TaskOne { public class Person { public...

[UWP/MVVM] Привязка к изменению данных в классе ViewModel
Всем доброго времени суток! Начал изучать MVVM, вроде как все более-менее понятно, но вот как...

4
Модератор
Эксперт .NET
15463 / 10708 / 2786
Регистрация: 21.04.2018
Сообщений: 31,522
Записей в блоге: 2
17.03.2019, 17:01 2
Цитата Сообщение от HeavyI Посмотреть сообщение
Программное создание элемента XAML в UWP:
Цитата Сообщение от HeavyI Посмотреть сообщение
Что делать в случае MVVM?
Честно говоря не знаю насколько в этом плане (MVVM) отличны WPF и UWP.
Но в WPF, в принципе, не должны создаваться UI элементы в коде. В коде нежелательно, вообще, работать с UI элементами, в том числе и использовать обработчики событий. Желательно использовать команды вместо обработчиков.
0
0 / 0 / 0
Регистрация: 17.03.2019
Сообщений: 9
17.03.2019, 18:57  [ТС] 3
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Но в WPF, в принципе, не должны создаваться UI элементы в коде.
Это очень странно. Если они не должны создаваться в коде, то как пользователю по нажатию кнопки создать какую-то новую форму с элементами для ввода данных?
В примере выше, где я запихал все в событие кнопки, создается некоторая форма. Как же тогда сделать подобное, если элементы не должны создаваться в коде?

В качестве примера могу привести пакет NuGet - Microsoft.Toolkit.Uwp.UI.Controls, в котором есть контрол - BladeView. В нем есть возможность создать именно такую панель, которая мне нужна. Но и там используются события, создается элемент UI в коде. Т.е. они делают неправильно?

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
    public interface IXamlRenderListener
    {
        void OnXamlRendered(FrameworkElement control);
    }
 
    public sealed partial class BladePage : IXamlRenderListener
    {
        private BladeView bladeView;
        private Button addBlade;
        private ResourceDictionary resources;
 
        public BladePage()
        {
            InitializeComponent();
        }
 
        public void OnXamlRendered(FrameworkElement control)
        {
            bladeView = control.FindChildByName("BladeView") as BladeView;
            addBlade = control.FindChildByName("AddBlade") as Button;
 
            if (addBlade != null)
            {
                addBlade.Click += OnAddBladeButtonClicked;
            }
 
            resources = control.Resources;
        }
 
        private void OnAddBladeButtonClicked(object sender, RoutedEventArgs e)
        {
            if (resources?.ContainsKey("BladeStyle") == true)
            {
                BladeItem bladeItem = new BladeItem()
                {
                    Style = resources["BladeStyle"] as Style
                };
 
                bladeView?.Items?.Add(bladeItem);
            }
        }
    }
Ни в коем случае не хочу с вами спорить, но если создавать элементы в коде нельзя, то как быть? Как сделать тоже самое, что делается в событии нажатия кнопки из кода в моем первом сообщении? Используя команды и в рамках паттерна MVVM.
0
1514 / 905 / 328
Регистрация: 17.05.2015
Сообщений: 3,417
17.03.2019, 19:45 4
HeavyI, нету простого способа. Вот например вы хотите динамически создавать кнопку.
Пишите шаблон, который будет определять расположение этих кнопок. Потом шаблон самой кнопки и определяете для нее вью модель. В основной вью модели создаете коллекцию вью моделей этих кнопок. Биндите Content Control на коллекцию этих вью моделей и задаете ему шаблон который создали в самом начале.
Не знаю как насчет контент контрола в UWP, но все остальное справедливо и в WPF и в UWP. Вот тут пример для WPF
MVVM и динамическое создание контролов
0
Модератор
Эксперт .NET
15463 / 10708 / 2786
Регистрация: 21.04.2018
Сообщений: 31,522
Записей в блоге: 2
17.03.2019, 20:45 5
Цитата Сообщение от HeavyI Посмотреть сообщение
Это очень странно. Если они не должны создаваться в коде, то как пользователю по нажатию кнопки создать какую-то новую форму с элементами для ввода данных?
Вы писали за патерн MVVM.
В нём ViewModel (и тем более Model) не обращаются к View. А UI элементы это, без вариантов, часть View.

В самой View большую часть работы по созданию UI элементов возлагают на XAML. То есть есть какие-то определённые в XAML стили, шаблоны, привязки. И используя их по данным получаемым из ViewModel View создаёт UI элементы.

В тех случаях когда XAML для создания UI элементов не хватает (особенно часто это бывает при создании UserControl, в т.ч. пример из NuGet приведённый Вами), то в View, конечно, можно использовать код C# для обращения к UI элементам или их создание.

НО! Подчёркиваю, только в рамках View!
Никакого управления UI элементам (как и, вообще, любой частью View) из ViewModel быть не должно!

В Вашем же коде обработчик явно относится к реакции ViewModel на действия пользователя. То есть нужно использовать какой-то шаблон (или UC). К кнопке привязать через команду вызов метода VM. В этом вызове (напрямую или через Модель) установить какой-то флаг. По установке этого флага View визуализирует Ваш шаблон.
0
17.03.2019, 20:45
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.03.2019, 20:45
Помогаю со студенческими работами здесь

Динамическое добавления XAML по методу MVVM
Это чисто для общего развития интересно. Можно и создать контрол из XAML-кода - с помощью...

[UWP] XAML Прокрутка динамичных элементов внутри StackPanel через ScrollViewer
Не работает ScrollViewer: &lt;ScrollViewer&gt; &lt;StackPanel...

Программное построение xaml файла
Рисую разные фигуры. Как программно построить из них xaml или xml файл?

Программное создание элемента управления
Доброго времени суток! Хотел поинтересоваться, как программно, на языке C#, создать элемент...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru