Question

I want to "Listen" to the my main ListView and if one or more of the items are removed, their clones in the other ListViews will be removed aswell.

For example:
I have 5 items in the main ListView
In the second ListView I have 2 cloned items (their position in the main ListView are 0 and 2)
In the third ListView I have another 2 cloned items (their position in the main `ListView are 0 and 4)

When I remove item number 0 from the main ListView, I want it to be removed from all its clones from the other ListViews.

Right now, what I am doing, is when item removed from the main ListView, I loop through the other ListViews to check if it matches to the removed one, if it does I remove them aswell.

I read about the ObservableCollection but I cant understand how to implement it for my needs... would appreciate help / easy guide that will explain simply how to do it.

EDIT:
This one is WinForms solution - I dont know how to convert it to WPF solution plus I am not even sure if this is what I need
http://www.codeproject.com/Articles/4406/An-Observer-Pattern-and-an-Extended-ListView-Event

Was it helpful?

Solution

To illustrate my point from the comments section, Say you have a UserControl called WindowItem that implements a Clone method:

<UserControl x:Class="WpfApplication1.WindowItem"
         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" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
      <Button Content="Click me"/>  
    </Grid>
</UserControl>

I create a class that will hold mutiple collections of WindowItem

public class MainWindowViewModel
{
    public MainWindowViewModel()
    {

    }

    public ObservableCollection<WindowItem> FirstCollection { get; set; }

    public ObservableCollection<WindowItem> SecondCollection { get; set; }

    public ObservableCollection<WindowItem> ThirdCollection { get; set; }
}

I also create a View contaning three ListViews, binded to my collections via Data Bindings

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    xmlns:local="clr-namespace:WpfApplication1"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <StackPanel>
        <ListView ItemsSource="{Binding FirstCollection}"/>
        <ListView ItemsSource="{Binding SecondCollection}"/>
        <ListView ItemsSource="{Binding ThirdCollection}"/>
    </StackPanel>
</Grid>
</Window>

Next, in the constructor of my MainWindow (known as View), I set it's DataContext to be the class I created earlier (known as ViewModel in MVVM).

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new MainWindowViewModel();
    }
}

Now, I can create cloning of my user controls for the different collection, shown in different lists in my view and register to the CollectionChanged event of the first collection. Here is an example of doing so from the ViewModel constructor

    public MainWindowViewModel()
    {
        FirstCollection = new ObservableCollection<WindowItem>();
        SecondCollection = new ObservableCollection<WindowItem>();
        ThirdCollection = new ObservableCollection<WindowItem>();

        var windowItem = new WindowItem();
        FirstCollection.Add(windowItem);            
        SecondCollection.Add(windowItem.Clone());

        // Register to collection changes notifications
        FirstCollection.CollectionChanged += FirstCollectionChanged;
    }

FirstCollectionChanged will fire whenever the first collection changes. You can "listen" for a removal action, and then remove the matching items from you other collections.

     private void FirstCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Remove)
        {
            // Remove matching item from second and third collection.
        }
    }

You can test it by removing an item from the first collection

FirstCollection.RemoveAt(0);

Hope this helps

OTHER TIPS

Instead of adding and removing items directly to/from ListView object bind it to some collection(preferably Observable Collection) and add/remove the items from ObservableCollection, it will be reflected on your UI also.

eg

ObservableCollection<WindowItem> MyCollection=new ObservableCollection<WindowItem>();

then add items by

MyCollection.Add(new WindowItem(parameters));

And for displaying your items from cloned listviews add an event handler to your main ObservableCollection like

MyCollection.CollectionChanged+=new System.Collections.Specialized.NotifyCollectionChangedEventHandler(CollectionChanged);

and

void CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
    //bind your another listviews to cloned items
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top