This question continues of this question here, that the answer has gotten a little dense even. The idea is now to better sift through the filtering technique I explained earlier.
In the previous answer, I set up an example in Windows Forms with a screen containing three fields: ownership of the entity to be filtered, operator and condition.

At the click of checkbox Filter, would activate a function also called Filtrar:
private void checkBoxFiltrar_CheckedChanged(object sender, EventArgs e)
{
Filtrar(checkBoxFiltrar.Checked);
}
The function is below:
protected void Filtrar(bool checkFiltrar)
{
if (checkFiltrar)
clienteBindingSource.DataSource = context.Clientes
.Where(comboBoxCampoPesquisa.SelectedValue.ToString() + ".Contains(@0)", textBoxValor.Text)
.ToList();
else
clienteBindingSource.DataSource = context.Clientes.Local.ToBindingList();
dataGridView.Refresh();
}
Now we must include the logic to insert the correct operator in our code with dynamic LINQ. Before, as we only have columns string, put an extra operator, called "Contains":
namespace TesteWindowsForms.Models.Enums
{
public enum Condicao
{
[Display(Name = "Contém")]
Contem,
[Display(Name = "Igual")]
Igual,
[Display(Name = "Diferente")]
Diferente,
[Display(Name = "Maior")]
Maior,
[Display(Name = "Menor")]
Menor,
[Display(Name = "Maior ou Igual")]
MaiorOuIgual,
[Display(Name = "Menor ou Igual")]
MenorOuIgual
}
}
The most interesting way I found to implement an operator resolution by Enum is using Extensions, as the below:
public static class EnumExtensions
{
public static TAttribute GetAttribute<TAttribute>(this Enum enumValue)
where TAttribute : Attribute
{
return enumValue.GetType()
.GetMember(enumValue.ToString())
.First()
.GetCustomAttribute<TAttribute>();
}
public static String CondicaoParaLinq(this Condicao condicao)
{
switch (condicao)
{
case Condicao.Contem:
return ".Contains(@0)";
case Condicao.Diferente:
return " != @0";
case Condicao.Maior:
return " > @0";
case Condicao.MaiorOuIgual:
return " >= @0";
case Condicao.Menor:
return " < @0";
case Condicao.MenorOuIgual:
return " <= @0";
case Condicao.Igual:
default:
return " == @0";
}
}
}
Use:
protected void Filtrar(bool checkFiltrar)
{
if (checkFiltrar)
clienteBindingSource.DataSource = context.Clientes
.Where(comboBoxCampoPesquisa.SelectedValue.ToString() +
((Condicao)Enum.Parse(typeof(Condicao), comboBoxCondicao.SelectedValue.ToString())).CondicaoParaLinq(),
textBoxValor.Text)
.ToList();
else
clienteBindingSource.DataSource = context.Clientes.Local.ToBindingList();
dataGridView1.Refresh();
}
That is, I can filter now by "contains" or "equal" from the screen:

But it doesn’t make much sense to use larger, smaller or smaller or equal, for example, in fields string, right? It means that every time your search field changes, you will need to restrict operators.
For that, I created this Helper:
public static class CondicoesHelper
{
private static Dictionary<Type, IEnumerable<Condicao>> condicoesPorTipo = new Dictionary<Type, IEnumerable<Condicao>> {
{ typeof(String), new List<Condicao> { Condicao.Igual, Condicao.Diferente, Condicao.Contem } },
{ typeof(int), new List<Condicao> { Condicao.Igual, Condicao.Diferente, Condicao.Maior, Condicao.MaiorOuIgual, Condicao.Menor, Condicao.MenorOuIgual } },
{ typeof(long), new List<Condicao> { Condicao.Igual, Condicao.Diferente, Condicao.Maior, Condicao.MaiorOuIgual, Condicao.Menor, Condicao.MenorOuIgual } },
{ typeof(Guid), new List<Condicao> { Condicao.Igual, Condicao.Diferente } }
};
public static IEnumerable<dynamic> FiltrarCondicoesPorTipoDeCampo(Type tipoDoCampo)
{
return condicoesPorTipo[tipoDoCampo]
.Select(c => new
{
Valor = c.ToString(),
Texto = c.GetAttribute<DisplayAttribute>().Name
})
.AsEnumerable();
}
public static IEnumerable<dynamic> TodasAsCondicoes()
{
return Enum.GetValues(typeof(Condicao))
.Cast<Condicao>()
.Select(c => new
{
Valor = c.ToString(),
Texto = c.GetAttribute<DisplayAttribute>().Name
})
.AsEnumerable();
}
}
Now I will need to tie an event to the search field. When it changes, the conditions list should be updated. That is:
private void comboBoxCampoPesquisa_SelectedValueChanged(object sender, EventArgs e)
{
IEnumerable<dynamic> condicoes;
if (comboBoxCampoPesquisa.SelectedValue != null)
{
condicoes = CondicoesHelper.FiltrarCondicoesPorTipoDeCampo(typeof(Cliente).GetProperty(comboBoxCampoPesquisa.SelectedValue.ToString()).PropertyType);
} else
{
condicoes = CondicoesHelper.TodasAsCondicoes();
}
comboBoxCondicao.ValueMember = "Valor";
comboBoxCondicao.DisplayMember = "Texto";
comboBoxCondicao.DataSource = condicoes.ToList();
}
Once this has been done, I can comment on the fulfilment of the OnLoad:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
context.Clientes.Load();
clienteBindingSource.DataSource =
context.Clientes.Local.ToBindingList();
var camposPesquisa =
typeof(Cliente).GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public |
BindingFlags.NonPublic | BindingFlags.FlattenHierarchy)
.Select(p => new
{
Valor = p.Name,
Texto = p.GetCustomAttribute<DisplayNameAttribute>().DisplayName
}).ToList();
comboBoxCampoPesquisa.ValueMember = "Valor";
comboBoxCampoPesquisa.DisplayMember = "Texto";
comboBoxCampoPesquisa.DataSource = camposPesquisa;
//var condicoes = Enum.GetValues(typeof(Condicao))
// .Cast<Condicao>()
// .Select(c => new
// {
// Valor = c.ToString(),
// Texto = c.GetAttribute<DisplayAttribute>().Name
// })
// .ToList();
//comboBoxCondicao.ValueMember = "Valor";
//comboBoxCondicao.DisplayMember = "Texto";
//comboBoxCondicao.DataSource = condicoes;
viewModel = new FiltrosPesquisaViewModel
{
};
}
And the method Filtrar? Stay like this:
protected void Filtrar(bool checkFiltrar)
{
if (checkFiltrar)
clienteBindingSource.DataSource = context.Clientes
.Where(comboBoxCampoPesquisa.SelectedValue.ToString() +
((Condicao)Enum.Parse(typeof(Condicao), comboBoxCondicao.SelectedValue.ToString())).CondicaoParaLinq(),
Convert.ChangeType(textBoxValor.Text, typeof(Cliente).GetProperty(comboBoxCampoPesquisa.SelectedValue.ToString()).PropertyType))
.ToList();
else
clienteBindingSource.DataSource = context.Clientes.Local.ToBindingList();
dataGridView1.Refresh();
}
To test, I put an extra column on the screen, "Number of Users", which is integer:


Finally, the operators are filtered according to the field type:


Let’s get back to what we talked about here, right?
– Leonel Sanches da Silva
@Gypsy omorrisonmendez excuse guy was my mistake, I thought I could not reference the question another link . I edited and put the question referenced
– Aprendiz