Member 12008812 Ответов: 1

Как создать несколько экземпляров usercontrol через цикл в MVVM


Привет,
У меня есть форма окна, в которой я выбираю значение из combobox.Теперь на основе выбранного значения, если у меня есть 3 элемента для этого 3 раза пользовательский элемент управления должен отображаться с текстовыми полями в каждом пользовательском элементе управления.Как я могу добиться создания нескольких экземпляров одного и того же пользовательского элемента управления в mvvm
MAinWIndow.Xaml
 <ItemsControl ItemsSource="{Binding Bindgrid}" Margin="26,277,281,136">
            <itemscontrol.itemtemplate>
                <DataTemplate DataType="{x:Type VM:MRRUserViewModel}">
                    <local:MMRUserControl />
                
            
        

here bindgrid is the observable collection which hold the value to be displayed in the user control textbox
VM:MRRUserViewModel it is the view model of usercontrol which calls the method that gives the result of bindgrid


Что я уже пробовал:

Я могу показать только один экземпляр пользовательского элемента управления

1 Ответов

Рейтинг:
8

Graeme_Grant

Использовать ObservableCollection удержание моделей или видовых моделей данных, которые будут отображаться в нескольких UserControls. Затем в код XAML файл, используйте ItemsControl (завернутый в ScrollViewer контроль или ListBox и установить DataTemple с UserControl.

ОБНОВЛЕНИЕ: Вот рабочий пример для вас, как вы просили...

Модели и ViewModels могут иметь свойства, которые могут изменяться. Вот базовый класс, который работает с интерфейсом привязки INotifyPropertyChanged:

public abstract class ObservableBase : INotifyPropertyChanged
{
    public void Set<TValue>(ref TValue field, TValue newValue, [CallerMemberName] string propertyName = "")
    {
        if (EqualityComparer<TValue>.Default.Equals(field, default(TValue)) || !field.Equals(newValue))
        {
            field = newValue;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

Примечание: это НЕ требуется для этого примера приложения, но здесь для тщательности для системы привязки.

Для нашего примера приложения нам нужна модель данных для привязки каждого элемента в приложении. ObservableCollection в MainViewModel класс:
public class PersonModel : ObservableBase
{
    private string name;
    public string Name
    {
        get { return name; }
        set { Set(ref name, value); }
    }

    private int age;
    public int Age
    {
        get { return age; }
        set { Set(ref age, value); }
    }
}

Теперь мы можем определить наши MainViewModel это будет содержать нашу коллекцию объектов, которые будут отображаться в MainWindow ПОЛЬЗОВАТЕЛЬСКИЙ ИНТЕРФЕЙС
public class MainViewModel
{
    public MainViewModel()
    {
        Mock();
    }

    public ObservableCollection<PersonModel> Persons { get; set; }
        = new ObservableCollection<PersonModel>();

    private Random rand = new Random();

    private void Mock()
    {
        for (int i = 0; i < 10; i++)
        {
            Persons.Add(new PersonModel
            {
                Name = string.Format("Person {0}", i),
                Age = rand.Next(20, 50)
            });
        }
    }
}

Теперь мы определяем наш шаблон элемента в UserControl по мере необходимости в этот вопрос:
<UserControl

    x:Class="ItemsControlSample.PersonUserControl"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <TextBlock Text="{Binding Name}" Margin="10 3"/>
        <TextBlock Text="{Binding Age}" Margin="10 3" Grid.Column="1"/>
    </Grid>

</UserControl>

Наконец, теперь мы готовы определить наши MainWindow Представление пользовательского интерфейса для пользователя:
<Window

    x:Class="ItemsControlSample.MainWindow"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"



    mc:Ignorable="d"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"



    xmlns:local="clr-namespace:ItemsControlSample"



    Title="Basic ObservableCollection binding example"

    WindowStartupLocation="CenterScreen" Height="400" Width="360">

    <Window.DataContext>
        <local:MainViewModel/>
    </Window.DataContext>

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition />
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <Grid.Resources>
            <DataTemplate DataType="{x:Type local:PersonModel}">
                <local:PersonUserControl/>
            </DataTemplate>
        </Grid.Resources>

        <TextBlock Text="ItemsControl Example" FontWeight="Bold" Margin="4 10"/>
        <Border BorderThickness="1" BorderBrush="Silver" Margin="4" Grid.Row="1">
            <ScrollViewer HorizontalScrollBarVisibility="Hidden"

                          VerticalScrollBarVisibility="Auto">
                <ItemsControl ItemsSource="{Binding Persons}"/>
            </ScrollViewer>
        </Border>

        <TextBlock Text="ListBox Example" FontWeight="Bold" Margin="4 10" Grid.Column="1"/>
        <ListBox ItemsSource="{Binding Persons}" Margin="4" Grid.Row="1" Grid.Column="1">
            <ListBox.ItemContainerStyle>
                <Style TargetType="ListBoxItem">
                    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                </Style>
            </ListBox.ItemContainerStyle>
        </ListBox>
    </Grid>

</Window>

Пример приложения показывает, как отобразить список Models содержится в ObservableCollection в переплете ViewModel одновременно с помощью ItemsControl и ListBox управление с помощью шаблона MVVM и системы привязки WPF.


Member 12008812

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

Graeme_Grant

Обновите свой вопрос образцом/макетом кода того, что вы пробовали, чтобы мы могли увидеть, что вы делаете в первую очередь.

Graeme_Grant

Пожалуйста, обновите вопрос с помощью примера кода, любых сообщений об ошибках (включая внутренние сведения об исключениях) и т.д., нажав на кнопку Улучшить вопрос виджет.

Member 12008812

Я обновил вопрос @Graeme

Graeme_Grant

Ваша виртуальная машина (ViewModel) и классы моделей отсутствуют в вашем образце. Так что непонятно, правильно ли вы работаете с ObservableCollection класс. Можно сломать систему привязки, если это не сделано правильно.

Maciej Los

Отличная работа!

Graeme_Grant

Спасибо Мацей! :)

Member 12008812

Я попробую это Грэм спасибо за усилия человек!

Member 12008812

Это сработало как заклинание именно то, что мне было нужно, спасибо большое!
У меня есть еще одна вещь,чтобы спросить @graeme, как я могу заставить пользовательский элемент управления повторяться несколько раз на основе элементов, которые имеет выбранное значение поля со списком.

Graeme_Grant

Если я правильно понял вопрос, вы хотите использовать a ComboBox для фильтрации элементов в списке по выбранным параметрам ComboBox предмет? Вы бы использовать Классу collectionviewsource[^] в качестве ItemsControl источник данных.

Member 12008812

Я предполагаю, что вы corect,но будет ли он динамически создавать один и тот же пользовательский элемент управления несколько раз

Graeme_Grant

Да. Возникает событие изменения коллекции и ItemsControl освежает вид.

Member 12008812

Не могли бы вы дать фрагмент для этого, поскольку я не понимаю, как это сделать?

Graeme_Grant

Я предоставил ссылку выше, которая показывает, как это может работать. По сути вы проходите мимо ObservableCollection в качестве источника данных CollectionViewSource, этот Filter с помощью SelectedItem из ComboBox и ItemsControl источником данных является CollectionViewSource.View. Этот View изменения, основанные на Filter. Когда Filter изменения, событие collection changed вызывается для CollectionViewSource.View и ItemsControl освежает вид.

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

Member 12008812

это здорово.Да, конечно, я попробую это сделать и, если застряну, отправлю новый вопрос
Большое спасибо чувак:-)

Member 12008812

Здравствуйте,я сделал Гугл, и я застрял в середине, где только один раз отображается пользовательский элемент управления, но не несколько раз, что является обязательным требованием.
это ссылка где я разместил вопрос
https://www.codeproject.com/Questions/1232545/Multiple-usercontrol-with-same-controls-textbox-co