简体   繁体   English

如何在WPF画布上显示可观察的收集项目

[英]How to show observable collection items on WPF canvas

I have an observable collection which is binded to datagrid. 我有一个绑定到datagrid的可观察的集合。 I can create wpf controls such as label,textbox etc into datagrid cells dynamically which in turn updates observable collection. 我可以将wpf控件(例如标签,文本框等)动态创建到datagrid单元中,从而依次更新可观察的集合。

Now, I would like to show this collection of items on canvas in rows and columns as in datagrid. 现在,我想在画布上以行和列的形式显示此项目集合,就像在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. 指定的Visual已经是另一个Visual的子级或CompositionTarget的根。

Thank you for your response. 感谢您的答复。

Where Data is a class defined as below. 其中Data是如下定义的类。

public class Data : INotifyPropertyChanged { 公共类数据: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. Inputfield和UIelement属性是datagrid的两列,其中包含动态创建的控件信息。

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 . 一个Visual只能有一个父对象,因此您必须首先将它从ObservableCollection (可能是您的DataGrid绑定到)中删除。但是,然后您将它放在Canvas而不是DataGrid

So if you're trying to have 2 "views" of your collection of UIElement s at the same time, then you'd have to clone the elements so they could go into the Canvas . 因此,如果您试图同时拥有UIElement集合的2个“视图”,则必须克隆这些元素,以便它们可以进入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 UIElement s), then define DataTemplate s which define the visuals for those data types. 首选的处理方式是将模型/视图模型保留在集合中(而不是UIElement ),然后定义DataTemplate ,后者定义这些数据类型的外观。 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. 然后,您可以将DataGridCanvas都绑定到相同的数据集合,但是当应用DataTemplates时,它们各自将具有自己的扩展视觉效果。

See these links: 请参阅以下链接:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM