New to WPF here. The application being built has a list of users being pulled from a database for display in a "Users" Window, navigable from a "Main" Window. The list seems to be transferred to the code behind, but the list of users isn't displaying in the "Users" Window ListBox. Does anyone see why this isn't displaying? Many thanks in advance!
"Main" Window directing:
UsersViewModel Usersvm = new UsersViewModel();
Usersvm.Users = new List<UserViewModel>();
DbEntities db = new DbEntities();
var pulledUsers = db.uspGetUsers().ToList();
foreach (var result in pulledUsers)
{
var pulledUser = new UserViewModel
{
FirstName = result.FirstName,
LastName = result.LastName,
EMail = result.Email,
UserID = result.UserID,
Position = result.Position,
EndDate = result.EndDate,
};
Usersvm.Users.Add(pulledUser);
}
new UsersWindow(Usersvm).Show();
UsersWindow code behind:
public partial class UsersWindow : Window
{
public UsersWindow(UsersViewModel uvm)
{
InitializeComponent();
listboxUsers.ItemsSource = uvm.Users;
}
}
UsersWindow.xaml:
<Window x:Class="DbEntities.UsersWindow"
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:DbEntities"
mc:Ignorable="d"
Title="UsersWindow" Height="Auto" Width="900">
<Window.Resources>
<Style x:Key="borderBase" TargetType="Border">
<Setter Property="BorderBrush" Value="Black" />
<Setter Property="BorderThickness" Value="1" />
</Style>
</Window.Resources>
<StackPanel>
<TextBlock x:Name="textBlock" Height="21" Margin="0,0,161,0" TextWrapping="Wrap"
Text="Users Page" VerticalAlignment="Top" RenderTransformOrigin="1.022,0.409" HorizontalAlignment="Right" Width="344"/>
<Grid>
<Grid Grid.IsSharedSizeScope="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="151*" />
<ColumnDefinition Width="95*" />
<ColumnDefinition Width="110*" />
<ColumnDefinition Width="351*" />
<ColumnDefinition Width="75*" />
<ColumnDefinition Width="110*" />
</Grid.ColumnDefinitions>
<Border Style="{StaticResource borderBase}">
<TextBlock HorizontalAlignment="Center" Text="Last Name" />
</Border>
<Border Grid.Column="1" Style="{StaticResource borderBase}">
<TextBlock HorizontalAlignment="Center" Text="First Name" />
</Border>
<Border Grid.Column="2" Style="{StaticResource borderBase}">
<TextBlock HorizontalAlignment="Center" Text="Position" />
</Border>
<Border Grid.Column="3" Style="{StaticResource borderBase}">
<TextBlock HorizontalAlignment="Center" Text="Email" />
</Border>
<Border Grid.Column="4" Style="{StaticResource borderBase}">
<TextBlock HorizontalAlignment="Center" Text="End Date" />
</Border>
<Border Grid.Column="5" Style="{StaticResource borderBase}">
<TextBlock HorizontalAlignment="Center" />
</Border>
<ListBox x:Name="listboxUsers" HorizontalAlignment="Center" Height="Auto" Margin="3,25,0,0" VerticalAlignment="Top" Width="889"
ItemsSource="{Binding Users}" Grid.ColumnSpan="6">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="LastNameColumn" />
</Grid.ColumnDefinitions>
<Border Style="{StaticResource borderBase}">
<TextBlock Text="{Binding LastName}"/>
</Border>
<Border Style="{StaticResource borderBase}">
<TextBlock Text="{Binding FirstName}"/>
</Border>
<Border Style="{StaticResource borderBase}">
<TextBlock Text="{Binding Position}"/>
</Border>
<Border Style="{StaticResource borderBase}">
<TextBlock Text="{Binding Email}"/>
</Border>
<Border Style="{StaticResource borderBase}">
<TextBlock Text="{Binding EndDate}"/>
</Border>
<Border Style="{StaticResource borderBase}">
<Button Content="Edit" x:Name="editButton" Click="editButton_Click"/>
</Border>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>
</Grid>
</StackPanel>
</Window>
And finally, the UsersViewModel, with a list of the user contact information:
public partial class UsersViewModel : Window
{
public List<UserViewModel> Users { get; set; }
}
EDIT (Solved): Ed Plunkett's comments and answer directly solved the original ListBox question, and using that input combined with ThyArtIsCode's, which was all neatly presented by Monty, the process is much more elegant. Thanks to all who replied - there's a ton of great learning material here.
Usersvm.Users
needs to be of typeObservableCollection<UserViewModel>
, notList
.List
won't notify then UI when its contents change.ObservableCollection
will. Second, UsersViewModel should not be a window. A window has nothing to do with a viewmodel. Next, it should implement INotifyPropertyChanged and firePropertyChanged
when Users is assigned a new collection Next, don't assign to ItemsSource in codebehind. That's not a binding. With the stuff above, the binding for that in your XAML should work correctly. – 15ee8f99-57ff-4f92-890c-b56153public UsersWindow
after Initial InitializeComponent();, just dovar vm = new UsersViewModel();
, initialize it, and thenDataContext = vm;
– 15ee8f99-57ff-4f92-890c-b56153