I am trying to create a WPF MVVM application that shows me a list of groups. The example is kept extra simple, for the described case it is probably too complicated. For this I created three UserControls:
It should looks like this:
________________________
| SideMenuControl |
| |
| Hello World |
| ____________________ |
| |GroupListControl | |
| | | |
| | ________________ | |
| | | Group1 | | |
| | | Group2 | | |
| | |________________| | |
| |____________________| |
|________________________|
However, I don't understand how to pass the ObservableCollection Groups to the GroupListControl. I guess it must succeed with DataContext , Content and/or ItemSource . Can anyone help me further?
GroupControl.xaml
<UserControl x:Class="WpfApp1.GroupControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
d:DesignHeight="30" d:DesignWidth="300">
<TextBlock Grid.Column="1" Text="{Binding Name}" VerticalAlignment="Center"/>
</UserControl>
GroupListControl.xaml
<UserControl x:Class="WpfApp1.GroupListControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Groups}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:GroupControl />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</UserControl>
SideMenuControl.xaml
<UserControl x:Class="WpfApp1.SideMenuControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Template>
<ControlTemplate TargetType="UserControl">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Text="Hello World"/>
<ContentPresenter Grid.Row="1"/>
</Grid>
</ControlTemplate>
</UserControl.Template>
</UserControl>
GroupViewModel.cs
using Microsoft.Toolkit.Mvvm.ComponentModel;
using System.Collections.ObjectModel;
namespace WpfApp1
{
public class GroupViewModel : ObservableObject
{
private Group _group;
public string Name
{
get => _group.Name;
set => SetProperty(_group.Name, value, _group, (model, name) => model.Name = name);
}
public GroupViewModel(Group model)
{
_group = model;
}
}
}
GroupCollectionViewModel.cs
using Microsoft.Toolkit.Mvvm.ComponentModel;
using System.Collections.ObjectModel;
namespace WpfApp1
{
public class GroupCollectionViewModel : ObservableObject
{
public ObservableCollection<GroupViewModel> Groups { get; set; }
public GroupCollectionViewModel()
{
Groups = new ObservableCollection<GroupViewModel>();
Groups.Add(new GroupViewModel(new Group { Name = "Group1" }));
Groups.Add(new GroupViewModel(new Group { Name = "Group2" }));
}
}
}
MainWindow.xaml
<Window x:Class="WpfApp1.MainWindow"
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:WpfApp1"
mc:Ignorable="d"
Title="TrayTool" Height="450" Width="800">
<local:SideMenuControl
DataContext="{Binding Groups}">
</local:SideMenuControl>
</Window>
MainWindow.xaml.cs
using System.Windows;
namespace WpfApp1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new GroupCollectionViewModel();
}
}
}
EDIT
If I replace the ContentPresenter element with the ScrollViewer element from GroupListControl.xaml (and remove the word Groups from the Binding Element) in SideMenuControl.xaml like below, I get the result that I want. But how can I achieve this with UserControls (GroupListControl and GroupControl)?
SideMenuControl.xaml (modified)
<UserControl x:Class="WpfApp1.SideMenuControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Template>
<ControlTemplate TargetType="UserControl">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Text="Hello World"/>
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:GroupControl />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</ControlTemplate>
</UserControl.Template>
</UserControl>
It seems like what you want is a DependencyProperty on your GroupListControl
. Eg, within your GroupListControl.cs file:
public static readonly DependencyProperty GroupsProperty =
DependencyProperty.Register(
"Groups",
typeof(ObservableCollection<GroupViewModel>),
typeof(GroupListControl)
);
public ObservableCollection<GroupViewModel> Groups
{
get => (ObservableCollection<GroupViewModel>)GetValue(GroupsProperty);
set => SetValue(GroupsProperty, value);
}
You can then bind to this in your XAML whenever you use a GroupListControl
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.