user1495759
user1495759

Reputation: 33

How to show observable collection items on WPF canvas

I have an observable collection which is binded to datagrid. I can create wpf controls such as label,textbox etc into datagrid cells dynamically which in turn updates observable collection.

Now, I would like to show this collection of items on canvas in rows and columns as in datagrid. Please help me to get that. I am using the code as below.

ObservableCollection<Data> Items= this.Items as ObservableCollection<Data>;

              if (this.Items != null)
                    {                        
                        foreach (var element in this.Items)
                        {
                            if (element != null)
                            {
                                UIElement getitem = (UIElement)element.InputField;

             //where inputfield is a property which holds the control.                             
             // It eturns the control that has created.
                                canvas.Children.Add(getitem);//adding the control to canvas
                            }
                        }
                    }

But it throwing the exception(on adding the control to canvas) as below. Specified Visual is already a child of another Visual or the root of a CompositionTarget.

Thank you for your response.

Where Data is a class defined as below.

public class Data : INotifyPropertyChanged {

    private UIElement _uIElement; 
    public UIElement UIElement
    {
        get { return _uIElement; } 
        set 
        {
            if (value != _uIElement) 
            {
                _uIElement = value;
                this.OnPropertyChanged("UIElement"); 
            } 
        } 
    }

    private UIElement _inputField;
    public UIElement InputField 
    {
        get { return _inputField; } 
        set 
        {
            if (value != _inputField) 
            {
                _inputField = value;
                this.OnPropertyChanged("InputField"); 
            } 
        } 
    } 

    #region INotifyPropertyChanged Members 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged(string name) 
    { 
        if (this.PropertyChanged != null) 
        { 
            this.PropertyChanged(this, new PropertyChangedEventArgs(name)); 
        } 
    }

} }

Inputfield and UIelement properties are the 2 columns of datagrid which holds the dynamic created controls information.

Upvotes: 0

Views: 1138

Answers (1)

Colin Smith
Colin Smith

Reputation: 12550

A Visual can only have one parent so you would have to remove it from the ObservableCollection (which presumably your DataGrid is bound to) first....but then you would have it on your Canvas but not on your DataGrid.

So if you're trying to have 2 "views" of your collection of UIElements at the same time, then you'd have to clone the elements so they could go into the Canvas.

What is the "Data" type...can you elaborate on it?

The preferred way to do things is keep your Model/View Models in the collection (not UIElements), then define DataTemplates which define the visuals for those data types. Then you can have the DataGrid and the Canvas both bind to the same collection of data, but they will each have their own inflated Visuals when the DataTemplates are applied.

See these links:

Upvotes: 3

Related Questions