Vincular o DynamicoBject a um datagrid com geração automática de colunas?
-
20-09-2019 - |
Pergunta
Ainda estou experimentando DynamicoBjects. Agora preciso de algumas informações: estou tentando vincular um objeto herdando do DynamicoBject a um WPF Datagrid (não Silverlight).
Como faço para obter o DataGrid para criar automaticamente suas colunas a partir das propriedades públicas disponíveis do objeto que normalmente são geradas em tempo de execução? Isso é possível, na verdade?
Solução
Não existe uma maneira uniforme de consultar propriedades dinâmicas, geralmente é esperado que você as conheça antes do tempo. Com DynamicObject
, os implementadores podem substituir GetMemberNames
E isso geralmente oferece as propriedades, no entanto, é realmente destinado à depuração, porque não há necessidade de que ele forneça todas as propriedades. Caso contrário, se for o seu DynamicObject
Você só precisa escrever seu próprio método para obter as propriedades com base na sua implementação dinâmica. Por exemplo ExpandoObject
permite consultar todas as propriedades usando o IDictionary
interface.
Portanto, depois de obter uma maneira de obter suas propriedades, você precisa informar ao DataGrid. Infelizmente com um datagrid, o problema com a implementação ICustomTypeDescriptor
Para informar o datagrid sobre suas propriedades é que o Datagrid recebe os typedEscriptores usando o tipo e não a instância, o que é um problema para objetos dinâmicos, no entanto, implementando ITypedList
Na coleção de DynamicoBjects, funcionará com a pequena gotcha de se você não implementar o não genérico IList
Interface em sua coleção, ela será retirada antes de chegar ao ponto em que verifica ITypeList
.
Então, em resumo, implemente uma coleção com ITypedList
e IList
. Com ITypedList
retornar nulo para GetListName
e apenas implementar GetItemProperties(PropertyDescriptor[] listAccessors)
; Ignorar listAccessors
e retorne um PropertyDescriptorCollection of PropertyDescriptors para cada membro nomeado com base na instância de objeto dinâmico melhor representado em sua lista (provavelmente apenas o primeiro objeto). Você precisa implementar uma subclasse do PropertyDescriptor, uma maneira fácil e geral para o valor Get/Set é usar a estrutura OpenSource Dinamitey
using System;
using System.ComponentModel;
using Dynamitey;
public class DynamicPropertyDescriptor:PropertyDescriptor
{
public DynamicPropertyDescriptor(string name) : base(name, null)
{
}
public override bool CanResetValue(object component)
{
return false;
}
public override object GetValue(object component)
{
return Dynamic.InvokeGet(component, Name);
}
public override void ResetValue(object component)
{
}
public override void SetValue(object component, object value)
{
Dynamic.InvokeSet(component, Name, value);
}
public override bool ShouldSerializeValue(object component)
{
return false;
}
public override Type ComponentType
{
get { return typeof(object); }
}
public override bool IsReadOnly
{
get { return false; }
}
public override Type PropertyType
{
get
{
return typeof (object);
}
}
}
Outras dicas
Eu acho que o DataGrid
usos TypeDescriptor
Para obter as propriedades do objeto para criar as colunas. Então você deve conseguir isso se o seu DynamicObject
implementos ICustomTypeDescriptor
. Implementar o GetProperties
Método para que ele retorne as propriedades dinâmicas do seu objeto.