动态绑定wpf

时间:2012-03-04 02:33:49

标签: wpf winforms binding

大家好,这是我的第一个问题:)

此示例在winform应用程序和wpf应用程序上测试以及在WPF上绑定的问题

  • winform一切正常,ICustomTypeDescriptor和网格绘制仅列添加到词典属性(名称年龄)和男性排除
  • WPF在网格上绘制的类人物的所有属性(姓名年龄男性)

关于这种情况的任何想法或wpf中等效ICustomTypeDescriptor的接口?

<Grid>
<DataGrid AutoGenerateColumns="True" Height="200" HorizontalAlignment="Left" Margin="90,30,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="325" />
</Grid>

List<Person> persons = new List<Person>();
persons.Add(new Person("Aymane", 30));
persons.Add(new Person("Raouia", 30));
grid.ItemsSource = persons; //wpf
grid.DataSource = persons; //winform

public class Person : ICustomTypeDescriptor
{
    Dictionary<string, object> Properties = new Dictionary<string, object>();

    public Person()
    {
        Properties.Add("Name", null);
        Properties.Add("Age", null);
    }

    public Person(string name, object value)
        : base()
    {
        Male = true;
        Name = name;
        Age = value;
    }

    public bool Male { get; set; }

    public object Age { get { return Properties["Age"]; } set { Properties["Age"] = value; } }

    public object Name { get { return Properties["Name"]; } set { Properties["Name"] = value; } }

    #region ICustomTypeDescriptor Members

    AttributeCollection ICustomTypeDescriptor.GetAttributes()
    {
        return TypeDescriptor.GetAttributes(this, true);
    }

    string ICustomTypeDescriptor.GetClassName()
    {
        return TypeDescriptor.GetClassName(this, true);
    }

    string ICustomTypeDescriptor.GetComponentName()
    {
        return TypeDescriptor.GetComponentName(this, true);
    }

    TypeConverter ICustomTypeDescriptor.GetConverter()
    {
        return TypeDescriptor.GetConverter(this, true);
    }

    EventDescriptor ICustomTypeDescriptor.GetDefaultEvent()
    {
        return TypeDescriptor.GetDefaultEvent(this, true);
    }

    PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty()
    {
        return TypeDescriptor.GetDefaultProperty(this, true);
    }

    object ICustomTypeDescriptor.GetEditor(Type editorBaseType)
    {
        return TypeDescriptor.GetEditor(this, editorBaseType, true);
    }

    EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes)
    {
        return TypeDescriptor.GetEvents(attributes, true);
    }

    EventDescriptorCollection ICustomTypeDescriptor.GetEvents()
    {
        return ((ICustomTypeDescriptor)this).GetEvents(null);
    }

    PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes)
    {
        List<PropertyDescriptor> props = new List<PropertyDescriptor>();

        props.Add(new PersonPropertyDescriptor("Name", attributes));
        props.Add(new PersonPropertyDescriptor("Age", attributes));

        return new PropertyDescriptorCollection(props.ToArray());
    }

    PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties()
    {
        return ((ICustomTypeDescriptor)this).GetProperties(null);
    }

    object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd)
    {
        return this;
    }

    #endregion

    class PersonPropertyDescriptor : PropertyDescriptor
    {
        public PersonPropertyDescriptor(string name, Attribute[] attrs)
            : base(name, attrs)
        {
        }

        public override bool CanResetValue(object component)
        {
            return true;
        }

        public override Type ComponentType
        {
            get { return typeof(Person); }
        }

        public override object GetValue(object component)
        {
            return ((Person)component).Properties[Name];
        }

        public override bool IsReadOnly
        {
            get { return false; }
        }

        public override Type PropertyType
        {
            get { return typeof(object); }
        }

        public override void ResetValue(object component)
        {
            ((Person)component).Properties[Name] = null;
        }

        public override void SetValue(object component, object value)
        {
            ((Person)component).Properties[Name] = value;
        }

        public override bool ShouldSerializeValue(object component)
        {
            return false;
        }
    }
}

2 个答案:

答案 0 :(得分:0)

要控制列生成处理AutoGeneratingColumn事件,您是否可以通过设置e.Cancel = true;来抑制列的生成

在你的情况下:

private void DataGridAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    var dataGrid = sender as DataGrid;
    if (dataGrid != null)
    {
        ICustomTypeDescriptor typeDescriptor =
            dataGrid.Items[0] as ICustomTypeDescriptor;
        if (typeDescriptor != null)
        {
            var props = typeDescriptor.GetProperties();

            if (!props.Contains((PropertyDescriptor)e.PropertyDescriptor))
            {
                e.Cancel = true;
            }
        }
    }
}

使用DataGrid定义:

    <DataGrid
        AutoGenerateColumns="True"
        Height="311"
        HorizontalAlignment="Left"
        Name="dataGrid1"
        VerticalAlignment="Top"           
        Width="509"
        AutoGeneratingColumn="DataGridAutoGeneratingColumn">

给出了理想的结果。

答案 1 :(得分:0)

这里正确实现了ICustomTypeDescriptor&amp; ITypedList

namespace CustomTypeDescriptor

{

class Row : ICustomTypeDescriptor { }

class RowsCollection : List<Row>, ITypedList { }

class Table : IListSource, IEnumerable<Row>, IEnumerator<Row>
{
    RowsCollection Rows { get; set; }
}

}