Cannot force WPF ListView to bind to ObservableCollection

I first played with WPF, especially using the ListView, which I want to bind to the ObservableCollection, which is a property on the code page. Right now, I'm just trying to figure out how everything works, so I tried to keep it simple. Unfortunately, I do not quite understand what I'm wrong with.

My page with the code below has a property that looks like this:

public ObservableCollection<Code> Code { get; set; } 

I have a button in the form that requests and populates the Code property.

The Code class is a simple POCO class:

 public class Code { public string Line { get; set; } } 

I added a namespace to the XAML window:

 <Window x:Class="SampleWPF.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:SampleWPF" Title="MainWindow" Height="350" Width="525" > 

And the ListView looks like this:

 <DockPanel Height="311" HorizontalAlignment="Left" Name="dockPanel1" VerticalAlignment="Top" Width="182"> <ListView Name="lstCode" ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Window, AncestorLevel=1}, Path=Code}" DisplayMemberPath="Line"> <ListView.View> <GridView> <GridViewColumn DisplayMemberBinding="{Binding Line}" /> </GridView> </ListView.View> </ListView> </DockPanel> 

I also tried setting the DataContext to the code behind the constructor with no luck, like this:

 this.DataContext = this; 

EDIT: moving this line after a line of code that creates a collection of fixed things (along with other proposed changes).

And I also tried to explicitly set the ItemSource in the code (in my click handler):

 this.lstCode.ItemsSource = this.Code; 

I looked through a few examples, but I still don't see anything here (not particularly surprising).

+4
source share
1 answer

Uh, you're trying to do something simple with some terrible magic;) Your binding should look like {Binding Path=Code} . To make this work, you must also set the DataContext to this , as you wrote. This should give you the simplest binding. Magic with the search for ancestors is not needed here.

In advanced applications, you should use the Model-View-ViewModel template and set the data context for the ViewModel, not for this , but only for testing and testing WPF, this approach should be ok.

Here is an example:

 <Window x:Class="binding_test.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid> <ListView ItemsSource="{Binding Path=Code}" /> </Grid> 

And the code behind:

 using System.Collections.ObjectModel; using System.Windows; namespace binding_test { public partial class MainWindow : Window { public ObservableCollection<int> Code { get; set; } public MainWindow() { InitializeComponent(); Code = new ObservableCollection<int>(); Code.Add(1); this.DataContext = this; } } } 

And this is how you should create a listview for your sample. You have a special class, and you probably don't want to display the result of ToString() for each object. To display an item in any way possible, you must use the data template and create controls and bind them to the properties of the item that was in the list that you are linking to listview .

  <ListView ItemsSource="{Binding Code}"> <ListView.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Line}" /> </DataTemplate> </ListView.ItemTemplate> </ListView> 
+19
source

Source: https://habr.com/ru/post/1338316/


All Articles