Click here to Skip to main content
15,882,114 members
Home / Discussions / WPF
   

WPF

 
AnswerRe: window application form work in KIOSK Pin
ZurdoDev9-Feb-16 8:36
professionalZurdoDev9-Feb-16 8:36 
QuestionHow to Programatically click a Button on a navigated Frame Page Pin
Vimalsoft(Pty) Ltd14-Jan-16 3:22
professionalVimalsoft(Pty) Ltd14-Jan-16 3:22 
AnswerRe: How to Programatically click a Button on a navigated Frame Page Pin
Vimalsoft(Pty) Ltd14-Jan-16 5:40
professionalVimalsoft(Pty) Ltd14-Jan-16 5:40 
QuestionCustom FrameworkElement with child controls Pin
Kenneth Haugland12-Jan-16 7:51
mvaKenneth Haugland12-Jan-16 7:51 
AnswerRe: Custom FrameworkElement with child controls Pin
Gerry Schmitz12-Jan-16 17:06
mveGerry Schmitz12-Jan-16 17:06 
GeneralRe: Custom FrameworkElement with child controls Pin
Kenneth Haugland13-Jan-16 1:39
mvaKenneth Haugland13-Jan-16 1:39 
GeneralRe: Custom FrameworkElement with child controls Pin
Gerry Schmitz13-Jan-16 6:25
mveGerry Schmitz13-Jan-16 6:25 
QuestionBinding a CompositeCollection to a Canvas (C#) Pin
Kenneth Haugland8-Jan-16 22:31
mvaKenneth Haugland8-Jan-16 22:31 
I have basically just copied the approach found here[^]. I just made some minor adjustments and wrapped the functionality inside a CustomControl:
C#
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;


public class MyCanvas : Canvas
{
    public static DependencyProperty ItemsSourceProperty =
        DependencyProperty.Register("ItemsSource",
        typeof(IEnumerable), typeof(MyCanvas),

        new FrameworkPropertyMetadata((IEnumerable)null,
            new PropertyChangedCallback(OnItemsSourcePropertyChanged)));

    private static Dictionary<INotifyCollectionChanged, MyCanvas> references = new Dictionary<INotifyCollectionChanged, MyCanvas>();

    public IEnumerable ItemsSource
    {
        get
        {
            return (IEnumerable)this.GetValue(ItemsSourceProperty);
        }
        set
        {
            this.SetValue(ItemsSourceProperty, value);
        }
    }

    private static void OnItemsSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var canvas = d as MyCanvas;
        repopulateChildren(canvas);


        if (canvas.ItemsSource is CompositeCollection)
        {
            CompositeCollection CollectionHolder = ((CompositeCollection)canvas.ItemsSource);

                foreach (CollectionContainer item in CollectionHolder)
            {

                ObservableCollection<UIElement> elements = (ObservableCollection<UIElement>)item.Collection;
                references.Add((elements as INotifyCollectionChanged), canvas);
                elements.CollectionChanged -= collectionChangedHandler;
                elements.CollectionChanged += collectionChangedHandler;
            }

        }
        else if (canvas.ItemsSource is IEnumerable<UIElement>)
        {
            var be = BindingOperations.GetBindingExpression(canvas, MyCanvas.ItemsSourceProperty);

            if (be != null)
            {
                var elements = (be.ResolvedSourcePropertyName == null ? be.ResolvedSource :
                    be.ResolvedSource.GetType().GetProperty(be.ResolvedSourcePropertyName).GetValue(be.ResolvedSource)) as INotifyCollectionChanged;

                if (elements != null)
                {
                    var cv = references.FirstOrDefault(i => i.Value == canvas);
                    if (!cv.Equals(default(KeyValuePair<INotifyCollectionChanged, MyCanvas>)))
                        references.Remove(cv.Key);


                    references[elements] = canvas;
                    elements.CollectionChanged -= collectionChangedHandler;
                    elements.CollectionChanged += collectionChangedHandler;
                }
            }
            else references.Clear();

        }

    }

    private static void collectionChangedHandler(object sender, NotifyCollectionChangedEventArgs e)
    {
        
        MyCanvas cv;

        if (references.TryGetValue(sender as INotifyCollectionChanged, out cv))
        {

            switch (e.Action)
        {
            case NotifyCollectionChangedAction.Add:
                foreach (var item in e.NewItems) cv.Children.Add(item as UIElement);
                break;
            case NotifyCollectionChangedAction.Remove:
                {
                    foreach (var item in e.OldItems)
                    {
                        cv.Children.Remove(item as UIElement);
                    }

                    break;
                }

            case NotifyCollectionChangedAction.Reset:
                repopulateChildren(cv);
                break;
        }
        }
    }


    public static DependencyProperty PerservedChildrenProperty = DependencyProperty.Register("PerservedChildren", typeof(int), typeof(MyCanvas), new PropertyMetadata(0));

    public int PerservedChildren
    {
        get
        {
            return (int)this.GetValue(PerservedChildrenProperty);
        }
        set
        {
            this.SetValue(PerservedChildrenProperty, value);
        }
    }

    private static void repopulateChildren(MyCanvas cv)
    {


        for (int i = cv.Children.Count - 1; i >= cv.PerservedChildren; i--)
        {
            cv.Children.RemoveAt(i);
        }

        var elements = (IEnumerable)cv.GetValue(ItemsSourceProperty );

        if (elements is CompositeCollection)
        {
            CompositeCollection CollectionHost = ((CompositeCollection)elements);
            foreach (CollectionContainer item in CollectionHost)
            {

                foreach (UIElement pp in item.Collection)
                {
                    if (!(cv.Children.Contains(pp)))
                        cv.Children.Add(pp);
                }
            }
        }
        else if (elements is IEnumerable<UIElement>)
        {
            foreach (UIElement elem in elements)
            {
                cv.Children.Add(elem);
            }
        }

    }

}


I can now bind an ObservableCollection<uielement> directly to the ItemsSource and it will work properly.

The problem appeared when I wanted to create support binding a CompositeCollection to it as well. The problem seems to be that I can't find the appropriate instance of the MyCanvas in the Dictionary, as it will only delete points found in one of the CollectionContainers bounded to the CompositeCollection. What am I missing here?

I did try and look at the ItemControl posted at Reference Source[^] since it seems to have support for CollectionContainers out of the box. I do realize that I can use an ItemControl to bind items to a canvas as well WPF Canvas, how to add children dynamically with MVVM code behind - Stack Overflow[^], and that could solve my problem, but I want to know how to make my code work with CollectionContainers.
AnswerRe: Binding a CompositeCollection to a Canvas (C#) Pin
Kenneth Haugland9-Jan-16 2:42
mvaKenneth Haugland9-Jan-16 2:42 
AnswerRe: Binding a CompositeCollection to a Canvas (C#) Pin
Richard Deeming11-Jan-16 3:51
mveRichard Deeming11-Jan-16 3:51 
GeneralRe: Binding a CompositeCollection to a Canvas (C#) Pin
Kenneth Haugland11-Jan-16 4:34
mvaKenneth Haugland11-Jan-16 4:34 
QuestionCan I run UITests on a WPF application. Pin
James_Parsons8-Jan-16 4:56
James_Parsons8-Jan-16 4:56 
AnswerRe: Can I run UITests on a WPF application. Pin
NickPace8-Jan-16 5:06
NickPace8-Jan-16 5:06 
QuestionLabel does not Get Updated Pin
Vimalsoft(Pty) Ltd6-Jan-16 20:33
professionalVimalsoft(Pty) Ltd6-Jan-16 20:33 
AnswerRe: Label does not Get Updated Pin
Mycroft Holmes6-Jan-16 20:45
professionalMycroft Holmes6-Jan-16 20:45 
GeneralRe: Label does not Get Updated Pin
Vimalsoft(Pty) Ltd6-Jan-16 20:49
professionalVimalsoft(Pty) Ltd6-Jan-16 20:49 
GeneralRe: Label does not Get Updated Pin
Mycroft Holmes6-Jan-16 21:04
professionalMycroft Holmes6-Jan-16 21:04 
GeneralRe: Label does not Get Updated Pin
Vimalsoft(Pty) Ltd6-Jan-16 21:09
professionalVimalsoft(Pty) Ltd6-Jan-16 21:09 
QuestionWPF/MVVM Unit Test Questions Pin
Kevin Marois5-Jan-16 5:46
professionalKevin Marois5-Jan-16 5:46 
AnswerRe: WPF/MVVM Unit Test Questions Pin
Pete O'Hanlon5-Jan-16 5:58
mvePete O'Hanlon5-Jan-16 5:58 
GeneralRe: WPF/MVVM Unit Test Questions Pin
Kevin Marois5-Jan-16 6:02
professionalKevin Marois5-Jan-16 6:02 
GeneralRe: WPF/MVVM Unit Test Questions Pin
Pete O'Hanlon5-Jan-16 8:26
mvePete O'Hanlon5-Jan-16 8:26 
GeneralRe: WPF/MVVM Unit Test Questions Pin
Mycroft Holmes6-Jan-16 20:49
professionalMycroft Holmes6-Jan-16 20:49 
GeneralRe: WPF/MVVM Unit Test Questions Pin
Pete O'Hanlon6-Jan-16 21:06
mvePete O'Hanlon6-Jan-16 21:06 
GeneralRe: WPF/MVVM Unit Test Questions Pin
Mycroft Holmes7-Jan-16 12:03
professionalMycroft Holmes7-Jan-16 12:03 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.