MikeT
MikeT

Reputation: 5500

Trouble with ObservableCollection and Binding

Ok i have a Class Mod defined as

public class Mod
{
    public Mod()
    {
        Data = new ObservableCollection<object>();
    }
    public Mod(Mod other)
    {
        Data = new ObservableCollection<object>(other.Data);
    }

    public ObservableCollection<object> Data { get; private set; }
}

and a control

    <TreeView x:Name="ItemList" DockPanel.Dock="Left" DataContext="{Binding Mod, Source={StaticResource Core}}" >
        <TreeView.Resources>
            <DataTemplate x:Key="TVTemplate" >
                <TreeViewItem Header="{Binding Name}" Tag="{Binding }" ToolTip="{Binding Desc}" />
            </DataTemplate>
        </TreeView.Resources>
        <TreeViewItem Header="Item1" ItemsSource="{Binding Data, ConverterParameter={x:Type local:Item1Type}, Converter={StaticResource OMTypeConverter}}" ItemTemplate="{DynamicResource TVTemplate}"/>
        <TreeViewItem Header="Item2" ItemsSource="{Binding Data, ConverterParameter={x:Type local:Item2Type}, Converter={StaticResource OMTypeConverter}}" ItemTemplate="{DynamicResource TVTemplate}"/>

the type converter is defined as

public class OMTypeConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        List<object> rtn = new List<object>();
        ObservableCollection<object> data= value as ObservableCollection<object>;
        if (data!= null)
        {
            Type type = parameter as Type;
            if (type != null)
            {
                var tmp = data.Where(o => type.IsInstanceOfType(o));
                rtn.AddRange(tmp);

            }
        }
        return rtn;
    }
}

when loading the window it works perfectly the type converter shows a value that is an empty Observable collection of objects, however when i then add an item to the OC nothing happened, the converter is not called and the items list appears unchanged on screen

i've confirmed from the code behind that the value has been added to the data collection

so why is the binding not being triggered to update the treeveiwitem?

Upvotes: 1

Views: 179

Answers (1)

Pragmateek
Pragmateek

Reputation: 13396

In your converter you are breaking the link with the original collection.

I can think of some workaround but there is a clean solution.

You should use two collections views on your Data.

Declare them in your code behind:

public ICollectionView Item1TypeView { get; set; }
public ICollectionView Item2TypeView { get; set; }

And initialize them in the constructor of your view:

Item1TypeView = new CollectionViewSource { Source = Data }.View;
Item1TypeView.Filter = e => e is Item1Type;
Item2TypeView = new CollectionViewSource { Source = Data }.View;
Item2TypeView.Filter = e => e is Item2Type;

Then bind each TreeView to one of them:

<TreeViewItem Header="Item1" ItemsSource="{Binding Item1TypeView}" ItemTemplate="{DynamicResource TVTemplate}"/>
<TreeViewItem Header="Item2" ItemsSource="{Binding Item2TypeView}" ItemTemplate="{DynamicResource TVTemplate}"/>

No need for converter anymore.

Upvotes: 1

Related Questions