Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Listbox & MVVM binding

I am following MVVM in C# and am attempting to display a view in a listbox.

I am setting the listbox itemsource (in code, not in binding and using the viewmodels collection) and then set the datatemplate to be my view in xaml. The issue I'm encountering is my view always loads with its default constructor values, if I remove the datacontext from the view however it loads fine.

Below is the listbox I am creating in xaml

<ListBox Name="lbCatalogues" HorizontalContentAlignment="Stretch">
     <ListBox.ItemTemplate>
         <DataTemplate>
              <view:CatalogueRowView/>
          </DataTemplate>
      </ListBox.ItemTemplate>
</ListBox>

This is the xaml for my view. If I remove the DataContext it works

<UserControl.DataContext>
    <model:CatalogueModel />
</UserControl.DataContext>

    <Grid Name="Container" >
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="50" />
        <ColumnDefinition Width="100" />
        <ColumnDefinition Width="100" />
        <ColumnDefinition Width="1*" />
        <ColumnDefinition Width="40" />
    </Grid.ColumnDefinitions>
    <!-- Catalogue_ID, UploadedTime, Client_ID, Name, Desc, Filesize -->
    <Label Name="lblCatalogueID" Content="{Binding Path=CatalogueID}" Grid.Column="0"/>
    <Label Name="lblUploadedTime" Content="{Binding Path=UploadedTime}" Grid.Column="1"/>
    <Label Name="lblCatalogueName" Content="{Binding Path=Name}" Grid.Column="2"/>
    <Label Name="lblCatalogueDescription" Content="{Binding Path=Description}" Grid.Column="3"/>
    <Label Name="lblFilesize" Content="{Binding Path=Filesize}" Grid.Column="4"/>
    <Grid/>

This is the code where I am setting the listbox ItemSource:

lbCatalogues.ItemsSource = catalogueViewModel.Records;

My question is how can I get the view to load correctly within the listbox so that each item in the listbox has a DataContext linked to that listbox Itemsource?

like image 678
Brett Avatar asked Jan 28 '26 08:01

Brett


1 Answers

You already know the answer: simply remove <UserControl.DataContext> from your UserControl

You are telling your UserControl to use a new instance of CatelogueModel for the DataContext, and this overrides any DataContext that is set when you use your UserControl. See MSDN's list of Dependency Property Precedence for more info

I do not ever recommend setting the DataContext inside a UserControl. It goes against how WPF is meant to work by having separate UI and data layers, and is a problem for anyone trying to use your UserControl

As for your question about each item in the ListBox linking to the ItemsSource, DataTemplates simply tell WPF how to draw an object. The data behind the object still remains.

For example, your ListBox contains a list of Record objects, and your DataTemplate is telling the ListBox to draw each one of those records with CatelogueRowView. The actual data behind the CatelogRowView is still your data object from catelogueViewModel.Records

like image 115
Rachel Avatar answered Jan 30 '26 02:01

Rachel



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!