Where() on Items that dont implement INotifyPropertyChanged

Feb 9, 2010 at 2:26 PM

Hello,

 

I have mentioned that i can only use 'Where' on a collection when the children implement INotifyPropertyChanged.

In my scenario i have a ReadOnlyObservableCollection. The children of this collection have some properties. This properties can only be set in the constructor and NEVER change.

Thats why they dont implement INotifyPropertyChanged. Without this interface i cannot use CLINQs Where-Method. But CLINQ would be very usefull in this scenario because my collection is continously adding and removing items.

My CLINQ-query would look like this:

var query = from obj in myReadOnlyObsCol where obj.Value <= otherObject.MaxValue orderby obj.Value;

The obj.Value-Property is fixed. But the otherObject is implementing INotifyPropertyChanged because its MaxValue-Property is updating sometimes.

I can not use a CollectionViewSource because the Filter-Event is not fired everytime when otherObject.MaxValue is changing. I would have to call refresh() all the time manually.

 

As a temporary workaround im goint to implement INotifyPropertyChanged in my class anyway. But i dont like implementing useless event that get never fired...

It would be very usefull if you could make Where() and the othe Methods also be callable for types that does not implement PropertyChanged. Maybe you can check if the interface is implemented and if not you just dont register a PropertyChanged-Handler and always work with the current value.

Greetings,

 

Lector

Feb 21, 2011 at 9:28 PM

Hello Lector,

i have got the same problem.

i made a small research and it seems that changing the objects used in the where-clause does not end with an Updating of the list as suspected

i made a small wpf application that demonstrates this. its a WPF App.

does anyone know if Clinq will get developed any further to support such scenarios ??

MainWindow.xaml.cs

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;
using System.ComponentModel;
using ContinuousLinq;

namespace ClinqTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        System.Collections.ObjectModel.ObservableCollection<Cow> cowList =
                new System.Collections.ObjectModel.ObservableCollection<Cow>();


        public Cow CompareCow { get; set; }

        public IEnumerable<Cow> CowList
        {
            get
            {
                return from x in cowList where CompareCow == null || x.Name == CompareCow.Name select x;
            }
        }
                
        public MainWindow()
        {
            CompareCow = new Cow("Hansi");
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            cowList.Add(new Cow(newCowsName.Text));
        }
    }

    public class Cow : INotifyPropertyChanged
    {
        public Cow(string name)
        {
            m_name = name;
        }

        private string m_name;

        public string Name
        {
            get
            {
                return m_name;
            }

            set
            {
                m_name = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("Name"));
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public override string ToString()
        {
            return Name;
        }
    }
}

MainWindow.xaml

 

<Window x:Class="ClinqTest.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" Name="self">
    <StackPanel>
        <ListBox Name="listBox" ItemsSource="{Binding ElementName=self, Path=CowList}"/>
        <TextBox Name="newCowsName" />
        <Button Content="Add Cow" Click="Button_Click" />
        <TextBlock>Filter this cow name</TextBlock>
        <TextBox Text="{Binding ElementName=self,Path=CompareCow.Name}"/>
    </StackPanel>
</Window>