Search code examples
prism

How to put usercontrol in itemsControl in wpf prism


I want to insert user control to itemscontrol in wpf using prism. The user control is printed, but I don't know how to do data binding.

ViewA.xaml

<Grid>
        <ItemsControl ItemsSource="{Binding People}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <ContentControl Grid.Row="1" Margin="10"
                        prism:RegionManager.RegionName="PersonDetailsRegion"
                        prism:RegionManager.RegionContext="{Binding}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>

ViewAViewModel.cs

private ObservableCollection<Person> _people;
        public ObservableCollection<Person> People
        {
            get { return _people; }
            set { SetProperty(ref _people, value); }
        }

        public ViewAViewModel()
        {
            CreatePeople();
        }


        private void CreatePeople()
        {
            var people = new ObservableCollection<Person>();
            for (int i = 0; i < 10; i++)
            {
                people.Add(new Person()
                {
                    FirstName = String.Format("First {0}", i),
                    LastName = String.Format("Last {0}", i),
                    Age = i
                });
            }

            People = people;
        }

insert a menu item into viewA.

MenuItem.xaml

<Grid x:Name="LayoutRoot" Background="White">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <!-- First Name -->
        <TextBlock Text="First Name:" Margin="5" />
        <TextBlock Grid.Column="1" Margin="5" Text="{Binding FirstName}" />

        <!-- Last Name -->
        <TextBlock Grid.Row="1" Text="Last Name:" Margin="5" />
        <TextBlock Grid.Row="1" Grid.Column="1"  Margin="5" Text="{Binding LastName}" />

        <!-- Age -->
        <TextBlock Grid.Row="2" Text="Age:" Margin="5"/>
        <TextBlock Grid.Row="2" Grid.Column="1"  Margin="5" Text="{Binding Age}"/>
    </Grid>
![The current situation is as follows.][1]
 https://i.sstatic.net/1VBai.png

How to do data binding? please help me

thanks you


Solution

  • This won't work like this. You have to create the region on the "outside", i.e. on the ItemsControl and remove the ItemsSource binding. Then navigate multiple times to the items control-region to populate it.

    <ItemsControl prism:RegionManager.RegionName="PersonDetailsRegion"/>
    

    Alternatively, keep the binding of ItemsSource and remove the ContentControl inside and put DataTemplates somewhere for your views. Then populate it by putting the view models into the items source.

    <DataTemplate DataType={x:Type Person}"><PersonView /></DataTemplate>
    ...    
    <ItemsControl ItemsSource="{Binding People}"/>
    

    Personally, I'd prefer the second variant most of the time, because you evade the added complexity of packing your persons' information in navigation parameters and getting them back, not to speak of the much simpler PersonViewModel...