VARIAVEL NO LUGAR DE PROPRIEDADE E POSSIVEL?
Estou pesquisando, mas não acho nada a respeito.
é possÃvel usar o conteúdo de uma variável, para substituir o nome de uma propriedade num objeto, como se passássemos um parâmetro para dizer qual o [Ô]Campo/Atributo[Ô] deste objeto queremos usar?
ex. ao invés de fazer assim....
Seria possÃvel fazer algo deste modo em negrito:
Um único problema se possÃvel, seria identificar o tipo do dado no campo, pois se for texto usa o .Trim(), mas se for número não usa. Queria otimizar o código e deixa-lo mais versátil, pois como está tem que fazer um Switch para cada grid e cada campo dele para ordenar. Dessa forma seria muito mais simples.
é possÃvel usar o conteúdo de uma variável, para substituir o nome de uma propriedade num objeto, como se passássemos um parâmetro para dizer qual o [Ô]Campo/Atributo[Ô] deste objeto queremos usar?
ex. ao invés de fazer assim....
private void grid_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
List<InstrutoresModelo> instrutor = grid.DataSource as List<InstrutoresModelo>;
switch (grid.Columns[e.ColumnIndex].Name)
{
case [Ô]Nome[Ô]:
instrutor = instrutor.OrderBy(c => c.Nome.Trim()).ToList();
break;
case [Ô]IDInstrutor[Ô]:
instrutor = instrutor.OrderBy(c => c.IDInstrutor).ToList();
break;
}
grid.DataSource = instrutor;
}
Seria possÃvel fazer algo deste modo em negrito:
private void grid_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
List<InstrutoresModelo> instrutor = grid.DataSource as List<InstrutoresModelo>;
instrutor = instrutor.OrderBy(c => c[grid.Columns[e.ColumnIndex].Name].Trim().ToList();
grid.DataSource = instrutor;
}
Um único problema se possÃvel, seria identificar o tipo do dado no campo, pois se for texto usa o .Trim(), mas se for número não usa. Queria otimizar o código e deixa-lo mais versátil, pois como está tem que fazer um Switch para cada grid e cada campo dele para ordenar. Dessa forma seria muito mais simples.
Você já tentou ao invés de reorganizar o datasource usar o método Sort do DataGridView?
http://msdn.microsoft.com/pt-br/library/0868ft3z(v=vs.100).aspx
http://msdn.microsoft.com/pt-br/library/0868ft3z(v=vs.100).aspx
Sim! E é bem simples, basta usar em cada propriedade seu respectivo Decoration [Ô]DisplayName[Ô]:
public class Cliente
{
[DisplayName([Ô]Nome do cliente[Ô])]
public string Nome {get; set;}
[DisplayName([Ô]Data de nascimento[Ô])]
public DateTime? DataNascimento {get; set;}
}
Vi o código, mas não funciona. O Grid é configurado para selecionar os registros por linha, o código exige que seja selecionada uma coluna, aà vai sempre para msgbox que pede pra selecionar uma coluna simples e não dá.
Tentou como eu mostrei, com o atributo?
Kerplunk não entendi, esse DisplayName fica dentro da classe entidade antes de cada campo?
Incluà lá, mas DisplayName não é reconhecido pelo VS. Será que não existe no VS 2008? Ou tem de incluir alguma using para habilitar ?
Uma coisa não entendi na sua resposta, o nome do campo na instância já aparece normal:
instrutor = instrutor.OrderBy(c => c.IDInstrutor).ToList();
Veja: c.IDInstrutor
O que eu gostaria é ao invés de declarar cada campo separadamente, usar uma referência ao nome da coluna selecionada no clique dentro dessa instrução, assim reduzindo muitas linhas de código.
instrutor = instrutor.OrderBy(c => c[grid.Columns[e.ColumnIndex].Name].Trim().ToList();
Assim: c[grid.Columns[e.ColumnIndex].Name].
Incluà lá, mas DisplayName não é reconhecido pelo VS. Será que não existe no VS 2008? Ou tem de incluir alguma using para habilitar ?
Uma coisa não entendi na sua resposta, o nome do campo na instância já aparece normal:
instrutor = instrutor.OrderBy(c => c.IDInstrutor).ToList();
Veja: c.IDInstrutor
O que eu gostaria é ao invés de declarar cada campo separadamente, usar uma referência ao nome da coluna selecionada no clique dentro dessa instrução, assim reduzindo muitas linhas de código.
instrutor = instrutor.OrderBy(c => c[grid.Columns[e.ColumnIndex].Name].Trim().ToList();
Assim: c[grid.Columns[e.ColumnIndex].Name].
Exato, acima da declaração de cada propriedade, coloque aquele decoration(DisplayName), e não esqueça do using, que fica no topo:
using System.ComponentModel;
using System.ComponentModel;
Citação::
Vi o código, mas não funciona. O Grid é configurado para selecionar os registros por linha, o código exige que seja selecionada uma coluna, aà vai sempre para msgbox que pede pra selecionar uma coluna simples e não dá.
Aquilo é apenas um exemplo, você não precisa fazer como está no exemplo da documentação, que no caso usa um button para organizar as colunas e por isso precisa que uma esteja selecionada, só que tem um outro problema ai, como você está usando um List<T> o sort do grid não funciona também.
Existe uma outra alternativa, que torna até mais fácil fazer isso, você pode usar a seguinte classe para permitir que qualquer objeto que implemente IList<T> sirva como fonte de dados com suporte a Sort
public class SortableBindingListCollection<T> : BindingList<T>
{
private bool isSorted;
private ListSortDirection sortDirection;
private PropertyDescriptor sortProperty;
public SortableBindingListCollection(IList<T> list)
: base(list)
{
}
public void Sort(string field, ListSortDirection direction)
{
if (this.Count > 0)
{
PropertyDescriptorCollection properties =
TypeDescriptor.GetProperties(this.Items[0]);
PropertyDescriptor myProperty = properties.Find(field,
false);
if (myProperty != null)
ApplySortCore(myProperty, direction);
}
}
protected override bool SupportsSortingCore
{
get { return true; }
}
protected override bool IsSortedCore
{
get { return isSorted; }
}
protected override ListSortDirection SortDirectionCore
{
get { return sortDirection; }
}
protected override PropertyDescriptor SortPropertyCore
{
get { return sortProperty; }
}
protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
{
sortProperty = prop;
sortDirection = direction;
List<T> list = (List<T>)Items;
list.Sort(delegate(T lhs, T rhs)
{
if (sortProperty != null)
{
isSorted = true;
object lhsValue = lhs == null ? null :
sortProperty.GetValue(lhs);
object rhsValue = rhs == null ? null :
sortProperty.GetValue(rhs);
int result =
System.Collections.Comparer.Default.Compare(lhsValue, rhsValue);
if (sortDirection == ListSortDirection.Descending)
{
result = -result;
}
return result;
}
else
{
isSorted = false;
return 0;
}
});
}
protected override void RemoveSortCore()
{
sortDirection = ListSortDirection.Ascending;
sortProperty = null;
}
}
O que muda no seu código ai é que você não precisa usar o evento ColumnHeaderMouseClick mais, se você criou as colunas manualmente só precisa se certificar que o SortMode delas está como automático, então na hora de definir o DataSource do grid você deve fazer algo do tipo
grid.DataSource = new SortableBindingListCollection<InstrutoresModelo>(seuListComOsDados);
Assim o sort deve funcionar automaticamente quando clicar no header sem precisar de mais nenhum código.
Ocelot Criei uma classe como você disse, mas tá dando vários erros veja:
Erro 1:
Erro 2:
Erro 3:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace HCSGI
{
// aqui entrou todo o seu código da classe
Erro 1:
public SortableBindingListCollection(IList<T> list) : [txt-color=#e80000]base(list)
[/txt-color]
{
} // o erro na parte vermelha diz: [Ô]object does not contain a constructor that takes [ô]1[ô] arguments[Ô]
Erro 2:
public void Sort(string field, ListSortDirection direction)
{
if [txt-color=#e80000](this.Count > 0[/txt-color]) // operador [ô]>[ô] cannot be applied to operands of type [ô]method group [ô]and [ô]int[ô]
{
// aqui não tem as diretivas do assembled, quais são ?
[txt-color=#e80000]PropertyDescriptorCollection properties [/txt-color]=
[txt-color=#e80000]TypeDescriptor[/txt-color].GetProperties(this.[txt-color=#e80000]Items[/txt-color][0]);
[txt-color=#e80000]PropertyDescriptor[/txt-color] myProperty = properties.Find(field,
false);
if (myProperty != null)
ApplySortCore(myProperty, direction);
}
}
Erro 3:
protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
{
sortProperty = prop;
sortDirection = direction;
List<T> list = (List<T>)[txt-color=#e80000]Items[/txt-color]; //Não existe no contexto atual
list.Sort(delegate(T lhs, T rhs)
{
if (sortProperty != null)
{
isSorted = true;
object lhsValue = lhs == null ? null :
sortProperty.GetValue(lhs);
object rhsValue = rhs == null ? null :
sortProperty.GetValue(rhs);
int result =
System.Collections.Comparer.Default.Compare(lhsValue, rhsValue);
if (sortDirection == [txt-color=#e80000]ListSortDirection[/txt-color].Descending) //Não existe no contexto atual
{
result = -result;
}
return result;
}
else
{
isSorted = false;
return 0;
}
});
}
protected override void RemoveSortCore()
{
sortDirection = [txt-color=#e80000]ListSortDirection[/txt-color].Ascending; //Não existe no contexto atual
sortProperty = null;
}
Eu devia ter passado os namespaces necessários, mas são apenas dois que são necessários para esta classe
using System.Collections.Generic;
using System.ComponentModel;
Adicionando estes using deve resolver todos os erros.
using System.Collections.Generic;
using System.ComponentModel;
Adicionando estes using deve resolver todos os erros.
Apenas para registrar aqui o que já respondi para o LUIS HERRERA por PM, o próprio DataGridView já sabe ordenar os itens dele sozinho sem você precisar fazer nada.
O problema é que para isso o DataSource dele precisa dar suporte a ordenação, coisa que neste caso, um List<T> não tem suporte.
Para resolver o problema se usa então esta classe SortableBindingListCollection<T>, que vai encapsular um IList<T> adicionado todos os métodos necessários para ordenar os dados, assim quando se passa este SortableBindingListCollection<T> como DataSource para o DataGridView ele já sabe o que fazer para ordenar os itens automaticamente quando se clica no cabeçalho das colunas.
O problema é que para isso o DataSource dele precisa dar suporte a ordenação, coisa que neste caso, um List<T> não tem suporte.
Para resolver o problema se usa então esta classe SortableBindingListCollection<T>, que vai encapsular um IList<T> adicionado todos os métodos necessários para ordenar os dados, assim quando se passa este SortableBindingListCollection<T> como DataSource para o DataGridView ele já sabe o que fazer para ordenar os itens automaticamente quando se clica no cabeçalho das colunas.
Tópico encerrado , respostas não são mais permitidas