SoloCodigo
CLR: .Net / Mono / Boo / Otros CLR => C# => Mensaje iniciado por: Sarampion en Viernes 28 de Noviembre de 2008, 15:21
-
Hola a toda aquella persona que este leyendo estas lineas.
El motivo de mi "post" es el siguiente: Estoy desarrollando un buscador por campo y valor (analogo a un buscador de Access, o a un buscador Customizado de un DataGrid de DevExpress). Trabajo sobre un Windows Form que contiene un ControlUser, y este ultimo esta conformado por TextEdit, Labels, ComboBox, etc. Los TextEdit estan bindeados a campos que obtengo de determinados BindingSource. Dicho buscador tiene un ComboBox que contiene los campos por el cual el operador va a poder buscar un usuario determinado. Dicho control (comboBox) quiero que contenga los campos bindeados a los TextEdit para que el operador elija un campo, en un TextEdit ingrese un valor acorde al campo seleccionado, presione Buscar y Wala!! currentUserChanged.
El tema recae justamente en obtener que campo esta bindeado a cada TextEdit. Para ello desarrolle, incompleto, lo siguiente:
MemberInfo[] mi =
assaSingleVisitEdit1.GetType().GetMembers(BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance); //assaSingleVisitEdit1 es el UserControl
foreach (MemberInfo info in mi)
{
if (info.GetType().FullName.Contains("System.Reflection.RtFieldInfo"))
{
if (info.Name.StartsWith("te"))
{
//IBindableComponent ibc = (IBindableComponent)info.DeclaringType;
//NECESITO EL CAMPO BINDEADO A CADA CONTROL
//IBindableComponent.DataBinding
//¿Como obtengo el Binding de cada componente?
//¿Como casteo un MemberInfo a un IBindingComponent?
FieldInfo fi = info as FieldInfo; //¿Es un avance o no lo es?
//¿Como llego a tener un objeto IBindingComponent? ¿Se puede o me estoy rompiendo la cabeza al pedo?
Propiedades.Add(info);
}
}
}
Como podran observador todas mis dudas e inconvenientes estan comentarizados en el codigo que les he copiado. Resumiendo, como puedo llegar a un objeto IBindingComponent para poder obtener el DataBinding de cada TextEdit. Por supuesto, no espero la solucion desde este codigo sino que acepto otras propuestas de desarrollo para poder llegar a mi objetivo.
Desde ya, muchas gracias a todos los que dediquen su tiempo para leer mi "post".
Saludos y exitos! Sarampion
-
Hola a todos!
El primer objetivo logre conseguirlo. Pude obtener todos los campos bindeados a los controles de mi UI a partir de la conjuncion de los siguientes procedimientos:
private readonly Collection<Control> MyControls = new Collection<Control>();
private void LoadControls(ControlCollection cc)
{
foreach (Control control in cc)
{
if (control.GetType().FullName.Equals("DevExpress.XtraEditors.TextEdit"))
{
if (!MyControls.Contains(control))
MyControls.Add(control);
}
else
{
if (control.Controls.Count > 0)
LoadControls(control.Controls);
}
}
}
private readonly Collection<BindingMemberInfo> MyBindingMemberInfo = new Collection<BindingMemberInfo>();
private void LoadDataBindings()
{
foreach (Control control in MyControls)
{
foreach (Binding binding in control.DataBindings)
{
MyBindingMemberInfo.Add(binding.BindingMemberInfo);
}
}
}
PASO 2 INCOMPLETO: Una vez que tengo los campos bindeados, quiero realizar la busqueda por dicho campo y por un valor especifico que introduce el operador a partir de la siguiente linea de codigo:
BindingMemberInfo memberSelected = (BindingMemberInfo) bp.PropertySelected;
assaSingleVisitEdit1.CiDataSource.Find(memberSelected.BindingMember, bp.ValueToFound);
CiDataSurce es un objeto de BindingSource.
Cuando ejecuto esa linea me tira el siguiente mensaje de error: "Specified method is not supported"
¿Alguien sabe que es lo que origina este error y como se puede solucionar?
Muchas gracias a todos!
Saludos coordiales, Sarampion!
-
Como he comentado en el "post" anterior, en el momento de realizar la busqueda recibia el error "Specified method is not supported". Buscando y buscando me tope con el causante del problema: Cuando se realiza una busqueda a traves del metodo Find() de un BindingSource es necesario implementar el override del metodo FindCore(). El error indica que este ùltimo no esta implementado en la clase. Les copio a continuacion dicho metodo:
private int FindCore(PropertyDescriptor prop, object key, int index)
{
// Get the property info for the specified property.
PropertyInfo propInfo = typeof(T).GetProperty(prop.Name);
T item;
if (key != null)
{
// Loop through the the items to see if the key
// value matches the property value.
for (int i = index; i < Count; ++i)
{
item = (T)Items;
if (propInfo.GetValue(item, null).Equals(key))
return i;
}
}
return -1;
}
Otra solucion que le encontre a esto es trabajar con el objeto FilteredBindingList<> de la Csla de Rockford Lhotka que brinda el metodo Find(), y su utilidad es muy similar a la del metodo BindingSource.Find() pero en su lugar se trabaja con un IList<> y no con un IEnumerable<>.
FilteredBindingList<T> buscar = new FilteredBindingList <T>(IList<> argumento);
buscar.Find(string propiedad, object key) o buscar.Find(PropertyDescriptor propiedad, object key)
El metodo devuelve un int indicando la posicion dentro de la lista del objeto buscado.
A partir de aqui, su programa de Busqueda ya deberia funcionar, en mi caso no pero esto se ve vinculado a un desarrollo de mi aplicacion ya que bindeo a los tools campos provenientes de diferentes clases persisitidas que instancian cada una un BindingSource determinado. Mi busqueda se ve condicionada por que el type que debo indicarle al FilteredBindingList<T> no siempre va a ser el mismo por cada campo seleccionado.
En fin, espero haberles proveido informacion interesante y que los ayude para cumplir sus objetivos.
Desde ya, muchas gracias a todos los que estuvieron leyendo estos "post"!
Exitos!
Atentamente, Sarampion.