ListView issues
-
I have a WinForms app with an embedded WPF user control. The embedded WPF
UserControl
contains aListView
. The application implements aList
collection that MUST remain compatible with the already existing Winforms code (for various reasons that aren't important here, the list cannot inherit fromIBindingList
orObservableCollection
). For this reason, the WPFListView
isn't updated when the contents of the list changes, which means (I think) that I'm relegated to adding/changing the items manually when they've changed. Everything I've found on the web assumes that I'm using purely WPF (and an ObservableCollection), and thus assumes I'm using databinding (which I'm not, obviously). I know how to add items to theListView
manually, but how do I tell theListView
columns what property to use from the added item?.45 ACP - because shooting twice is just silly
-----
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001 -
I have a WinForms app with an embedded WPF user control. The embedded WPF
UserControl
contains aListView
. The application implements aList
collection that MUST remain compatible with the already existing Winforms code (for various reasons that aren't important here, the list cannot inherit fromIBindingList
orObservableCollection
). For this reason, the WPFListView
isn't updated when the contents of the list changes, which means (I think) that I'm relegated to adding/changing the items manually when they've changed. Everything I've found on the web assumes that I'm using purely WPF (and an ObservableCollection), and thus assumes I'm using databinding (which I'm not, obviously). I know how to add items to theListView
manually, but how do I tell theListView
columns what property to use from the added item?.45 ACP - because shooting twice is just silly
-----
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001Why bind to the
List
itself when you can bind to anObservableCollection
and add and remove items to thatObservableCollection
manually! and you should make thatObservableCollection
of a ViewModel of the actual list items. I think that should work the way you want. About setting the property to use for theListView
columns, use theDisplayMemberBinding
of theGridViewColumn
. It works even when adding items manually to theListView
's Items property.Eslam Afifi
-
Why bind to the
List
itself when you can bind to anObservableCollection
and add and remove items to thatObservableCollection
manually! and you should make thatObservableCollection
of a ViewModel of the actual list items. I think that should work the way you want. About setting the property to use for theListView
columns, use theDisplayMemberBinding
of theGridViewColumn
. It works even when adding items manually to theListView
's Items property.Eslam Afifi
I already said I cannot use
ObservableCollection
because that will break the winforms code that uses the list..45 ACP - because shooting twice is just silly
-----
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001 -
Why bind to the
List
itself when you can bind to anObservableCollection
and add and remove items to thatObservableCollection
manually! and you should make thatObservableCollection
of a ViewModel of the actual list items. I think that should work the way you want. About setting the property to use for theListView
columns, use theDisplayMemberBinding
of theGridViewColumn
. It works even when adding items manually to theListView
's Items property.Eslam Afifi
I'm pretty damned sure that John said he couldn't use an ObservableCollection, and he explained why he couldn't use it so your post added nothing to his question.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith
As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
-
I have a WinForms app with an embedded WPF user control. The embedded WPF
UserControl
contains aListView
. The application implements aList
collection that MUST remain compatible with the already existing Winforms code (for various reasons that aren't important here, the list cannot inherit fromIBindingList
orObservableCollection
). For this reason, the WPFListView
isn't updated when the contents of the list changes, which means (I think) that I'm relegated to adding/changing the items manually when they've changed. Everything I've found on the web assumes that I'm using purely WPF (and an ObservableCollection), and thus assumes I'm using databinding (which I'm not, obviously). I know how to add items to theListView
manually, but how do I tell theListView
columns what property to use from the added item?.45 ACP - because shooting twice is just silly
-----
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001John - you only need an ObservableCollection if you want to catch notification changes. In this case, you'd bind to the properties in exactly the same way you'd bind to an ObservableCollection. Here's a quick sample I whipped together for you:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;namespace BindToList
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
private List<MyListItem> _list;
public Window1()
{
InitializeComponent();\_list = new List<MyListItem>(); AddItem("John", "Simmons"); AddItem("Pete", "O'Hanlon"); AddItem("Clint", "Eastwood"); foreach (MyListItem item in \_list) { listBound.Items.Add((MyListItem)item); } } public List<MyListItem> MyList { get { return \_list; } set { \_list = value; } } public void AddItem(string forename, string surname) { \_list.Add(new MyListItem { ID = \_list.Count + 1, Forename = forename, Surname = surname }); }
}
public class MyListItem
{
private int _id;public int ID { get { return \_id; } set { \_id = value; } } private string \_forename; public string Forename { get { return \_forename; } set { \_forename = value; } } private string \_surname; public string Surname { get { return \_surname; } set { \_surname = value; } }
}
}Now, here's the XAML that goes with this:
<Window x:Class="BindToList.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<DataTemplate x:Key="myListTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ID}" />
<TextBlock Text="{Binding Forename}" />
<TextBlock Text="{Binding Surname}" />
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<ListBox x:Name="lis -
I already said I cannot use
ObservableCollection
because that will break the winforms code that uses the list..45 ACP - because shooting twice is just silly
-----
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001John Simmons / outlaw programmer wrote:
the list cannot inherit from IBindingList or ObservableCollection
I didn't say you should inherit from ObservableCollection. I said,
Eslam Afifi wrote:
bind to an ObservableCollection and add and remove items to that ObservableCollection manually
Maybe I wasn't clear enough. In this case, I'm sorry. But I meant to bind to an ObservableCollection not the List in question. Something like that,
List<A> \_aModels = new List<A>(); // the list not to be touched ObservableCollection<AViewModel> \_aViewModels = new ObservableCollection<AViewModel>(); // and adding to to the ObservableCollection when adding to the List to keep them in sync. the same for removing. var aModel = new A { X = \_random.Next(), Y = \_random.Next(), Z = \_random.Next() }; \_aModels.Add(aModel); \_aViewModels.Add(new AViewModel(aModel)); // bind the ObservableCollection to the ListView's ItemsSource
As for setting which property to use of columns. It works even when adding items manually to the ListView's Items property and not using ItemsSource. ItemsSource
<ListView.View>
<GridView>
<GridView.Columns>
<!-- the ViewModel exposes the X, Y and Z properties -->
<GridViewColumn Header="X" DisplayMemberBinding="{Binding X}" Width="100" />
<GridViewColumn Header="Y" DisplayMemberBinding="{Binding Y}" Width="100" />
<GridViewColumn Header="Z" DisplayMemberBinding="{Binding Z}" Width="100" />
</GridView.Columns>
</GridView>
</ListView.View>I replied to your question based on what I understood from it. You said you can't inherit from ObservableCollection and I don't think using a separate object of ObservableCollection would break the compatibility with the already existing windows forms code. If you mean you can't even use a separate instance of ObservableCollection because it breaks existing code, why would it break the code?
Eslam Afifi
-
John Simmons / outlaw programmer wrote:
the list cannot inherit from IBindingList or ObservableCollection
I didn't say you should inherit from ObservableCollection. I said,
Eslam Afifi wrote:
bind to an ObservableCollection and add and remove items to that ObservableCollection manually
Maybe I wasn't clear enough. In this case, I'm sorry. But I meant to bind to an ObservableCollection not the List in question. Something like that,
List<A> \_aModels = new List<A>(); // the list not to be touched ObservableCollection<AViewModel> \_aViewModels = new ObservableCollection<AViewModel>(); // and adding to to the ObservableCollection when adding to the List to keep them in sync. the same for removing. var aModel = new A { X = \_random.Next(), Y = \_random.Next(), Z = \_random.Next() }; \_aModels.Add(aModel); \_aViewModels.Add(new AViewModel(aModel)); // bind the ObservableCollection to the ListView's ItemsSource
As for setting which property to use of columns. It works even when adding items manually to the ListView's Items property and not using ItemsSource. ItemsSource
<ListView.View>
<GridView>
<GridView.Columns>
<!-- the ViewModel exposes the X, Y and Z properties -->
<GridViewColumn Header="X" DisplayMemberBinding="{Binding X}" Width="100" />
<GridViewColumn Header="Y" DisplayMemberBinding="{Binding Y}" Width="100" />
<GridViewColumn Header="Z" DisplayMemberBinding="{Binding Z}" Width="100" />
</GridView.Columns>
</GridView>
</ListView.View>I replied to your question based on what I understood from it. You said you can't inherit from ObservableCollection and I don't think using a separate object of ObservableCollection would break the compatibility with the already existing windows forms code. If you mean you can't even use a separate instance of ObservableCollection because it breaks existing code, why would it break the code?
Eslam Afifi
You've added an ObservableCollection when it's not needed. You can bind directly to a generic list, so adding the binding to the ObservableCollection is unecessary; the only reason to bind to ObservableCollection is to receive notifications when the list changes, which you can mimic without an ObservableCollection (after all, you're maintaining the same list twice here). As an item is added to the List, all you need to do is raise a CollectionChanged event when an item is added or removed from the list.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith
As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
-
You've added an ObservableCollection when it's not needed. You can bind directly to a generic list, so adding the binding to the ObservableCollection is unecessary; the only reason to bind to ObservableCollection is to receive notifications when the list changes, which you can mimic without an ObservableCollection (after all, you're maintaining the same list twice here). As an item is added to the List, all you need to do is raise a CollectionChanged event when an item is added or removed from the list.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith
As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
Yes, you are right. I'm aware of that, that's why I mentioned that the DisplayMemberBinding works when adding items to the Items manually. I tried both ways in a sample code before I first replied. This has just popped into my mind while I was reading your post, if it's not possible to make the List implement the INotifyCollectionChanged (If it's a class that inherits from List, which is what I understood from the question and the class is not to be touched. But I don't think implementing the interface would break existing code) then maybe creating a wrapper for (or inheriting from) the List (a custom List or just a List), implementing INotifyCollectionChanged and substituting the List with its wrapper (which would be implementing the interfaces of the original List) would be a better option. I haven't thought much about it and I'm interested to know what you think about it.
Eslam Afifi
-
Yes, you are right. I'm aware of that, that's why I mentioned that the DisplayMemberBinding works when adding items to the Items manually. I tried both ways in a sample code before I first replied. This has just popped into my mind while I was reading your post, if it's not possible to make the List implement the INotifyCollectionChanged (If it's a class that inherits from List, which is what I understood from the question and the class is not to be touched. But I don't think implementing the interface would break existing code) then maybe creating a wrapper for (or inheriting from) the List (a custom List or just a List), implementing INotifyCollectionChanged and substituting the List with its wrapper (which would be implementing the interfaces of the original List) would be a better option. I haven't thought much about it and I'm interested to know what you think about it.
Eslam Afifi
That would work. I'm currently writing an extended version of ObservableCollection that supports undo functionality, and it's simply a Collection wrapped up using INotifyCollectionChanged.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith
As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
-
That would work. I'm currently writing an extended version of ObservableCollection that supports undo functionality, and it's simply a Collection wrapped up using INotifyCollectionChanged.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith
As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
Nice. I'm looking forward to seeing it.
Eslam Afifi