Tengo un UserControl con varios campos que me gustaría vincular a un BindingSource. También me gustaría que el UserControl exponga alguna propiedad de BindingSource para que se pueda descartar en un Formulario y vincularlo a BindingSource en el formulario. ¿Hay una forma fácil de hacer esto? Me doy cuenta de que puedo vincular todos los controles del UserControl en su setter BindSource. Pero esto parece estar mal. ¿Hay algún BindingSource Proxy que me permita vincular BindingSource en el control de usuario a BindingSource en el formulario?Uso de un BindingSource en un UserControl
Respuesta
Según su pregunta, apenas puedo obtener lo que piensa hacer. Por lo tanto, haré todo lo posible para proporcionarle, espero, información interesante sobre ese asunto.
En primer lugar, consideremos el siguiente UserControl en un proyecto de software de gestión de clientes.
public partial class CustomerManagementUserControl : UserControl {
public CustomerManagementUserControl() {
InitializeComponent();
_customerBindingSource = new BindingSource();
}
public IList<ICustomer> DataSource {
set {
_customerBindingSource.DataSource = value;
}
}
private BindingSource _customerBindingSource;
}
En segundo lugar, consideremos el siguiente Formulario que debe ser su formulario de gestión de clientes.
public partial class CustomerManagementForm : Form {
public CustomerManagementForm() {
InitializeComponent();
_customerUserControl = new CustomerManagementUserControl();
_customerUserControl.Name = @"customerUserControl";
}
private void CustomerManagementForm_Load(object sender, EventArgs e) {
// CustomersFacade is simply a static class providing customer management features and requirements.
// Indeed, the GetCustomers() method shall return an IList<ICustomer>.
// The IList type and typed IList<T> are both intended to be bindable as a DataSource for DataBinding.
_customerUserControl.DataSource = CustomersFacade.GetCustomers();
this.Controls.Add(_customerUserControl);
}
private CustomerManagementUserControl _customerUserControl;
}
Si usted está esperando para usar la propiedad CustomerManagementUserControl.DataSource desde dentro de la ventana de propiedades, por favor considerar agregar el siguiente en la parte superior de la definición de la propiedad.
[System.ComponentModel.DesignTimeVisible(true), System.ComponentModel.DesignerCategory("CustomerUserControl"), System.ComponentModel.Description("Sets the CustomerUserControl DataSource property")]
Esta es una forma de hacer lo que supongo que podría querer hacer. Por otro lado, si lo que desea hacer es obtener lo más abstracto posible configurando un tipo diferente de objeto como su propiedad UserControl.BindingSource.DataSource, tendrá que escribir un método que pueda detectar el tipo de objeto. el objeto pasado, luego vincula las propiedades en consecuencia. Una buena manera en que podría ir, tal vez, es Reflexión, si se siente cómodo trabajando con ella. De cualquier modo que pueda imaginar trabajando con tales características de polimorfismo, tendrá que escribir usted mismo una interfaz que todos sus objetos enlazables deberán implementar. De esta forma, evitará los nombres de propiedad desconocidos, y cuando llegue el momento de vincular los controles de UserControl, podrá enlazar la propiedad correcta con el control correcto, y así sucesivamente.
Probemos el siguiente:
public interface IEntity {
double Id { get; set; }
string Number { get; set; }
string Firstname { get; set; }
string Surname { get; set; }
long PhoneNumber { get; set; }
}
public interface ICustomer : IEntity {
}
public interface ISupplier : IEntity {
string Term { get; set; }
}
public sealed Customer : ICustomer {
public Customer() {
}
public double Id { get; set; }
public string Number { get; set; }
public string Firstname { get; set; }
public string Surname { get; set; }
public long PhoneNumber { get; set; }
}
public sealed Supplier : ISupplier {
public Supplier() {
}
public double Id { get; set; }
public string Number { get; set; }
public string Firstname { get; set; }
public string Surname { get; set; }
public long PhoneNumber { get; set; }
public string Term { get; set; }
}
Teniendo en cuenta el código anterior, puede utilizar la propiedad DataSource de su UserControl para unirse con un IEntity, por lo que su propiedad podría recibir como este.
[System.ComponentModel.DesignTimeVisible(true), System.ComponentModel.DesignerCategory("CustomerUserControl"), System.ComponentModel.Description("Sets the CustomerUserControl DataSource property")]
public IList<IEntity> DataSource {
set {
_customerBindingSource.DataSource = value;
}
}
Dicho esto, si desea ir aún más lejos, usted podría exponer a los controles DataBindings las propiedades de su UserControl con el fin de ponerlos en tiempo de diseño. Teniendo esto en cuenta, querrá exponer su BindingSource como una propiedad pública para que también pueda configurarlo en tiempo de diseño, luego elija su DataMember de este BindinSource.
Espero que esto los ayude un poco o al menos, le proporcione algunas pistas para futuras búsquedas.
Si quería hacer todo esto de forma automática podría buscar el origen de enlace desde el formulario principal en el evento de carga de su control de usuario o algo por el estilo ...
Dim components As Reflection.FieldInfo = typ.GetField("components", Reflection.BindingFlags.DeclaredOnly Or Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic)
Dim lstBindingSources As New List(Of BindingSource)
For Each obj As Object In components.Components
Dim bindSource As BindingSource = TryCast(obj, BindingSource)
If bindSource IsNot Nothing Then
lstBindingSources.Add(bindSource)
End If
Next
If lstBindingSources.Count = 1 Then
MyBindingSource.DataSource = lstBindingSources(0).DataSource
End If
Si asigna el mismo referencia de objeto como origen de datos en dos fuentes de enlace, los controles no se actualizarán de forma coherente en el segundo origen de enlace.Posiblemente, un compromiso de las opciones anteriores es el siguiente:
- añadir temporalmente un BindingSource al control de usuario y utilizar el diseñador
VS
a establecer los enlaces a los controles. - trae el
designer.vb
en el editor de código. Busque todas las líneas"DataBindings.Add"
que fueron creadas por el diseñador. Cópialos todos en el bloc de notas. - elimine el bindingsource del diseñador y agregue una referencia de bindingsource en el código. Agregue una propiedad para el bindingsource con el mismo nombre que se utilizó en el diseñador. En el colocador de la propiedad, pegue todas las líneas del Bloc de notas anterior en el paso 2.
- En el evento Cargar del formulario, asigne el origen de enlace del formulario a la propiedad en el control de usuario. Si el control del usuario está incrustado en otro control de usuario, puede usar el evento del control padre generado a mano para hacer lo mismo.
Hay menos tipado y menos errores tipográficos porque el diseñador VS
está creando todos los nombres de propiedad de texto literal.
Sé que es una respuesta tardía; sin embargo, podría ser útil para alguien más leyendo esta publicación.
Tengo controles en un UserControl
vinculados a datos. Necesito tener un BindingSource
en el UserControl
para poder enlazar los controles en el momento del diseño. El "verdadero" BindingSource
, sin embargo, se encuentra en el Form
. En otras palabras, los controles en el UserControl
deben comportarse como si estuvieran sentados directamente en el formulario (o en un ContainerControl
en el formulario).
La idea detrás de esta solución es mirar para el DataSourceChanged
caso de la "real" BindingSource
y asignar su DataSource
a la BindingSource
locales cuando cambia. Con el fin de encontrar el "verdadero" BindingSource
dejo que el Form
(o Control
) que lo contiene implementar la siguiente interfaz:
public interface IDataBound
{
BindingSource BindingSource { get; }
}
Podemos mirar para el ParentChanged
caso de un control con el fin de saber cuándo se ha añadido a Form
o ContainerControl
. El problema aquí es que este ContainerControl
podría no haberse agregado al Form
(u otro ContainerControl
) aún en este momento. En este caso, nos suscribimos al evento ParentChanged
del último padre que encontramos en la cadena de padres y esperamos hasta que este último padre haya sido agregado, y así sucesivamente, hasta que encontremos un Control
o Form
implementando IDataBound
. Cuando se ha encontrado un IDataBound
, nos suscribimos al evento DataSourceChanged
de su BindingSource
.
public partial class MyUserControl : UserControl
{
private IDataBound _dataBoundControl;
private Control _parent;
public MyUserControl()
{
InitializeComponent();
if (LicenseManager.UsageMode == LicenseUsageMode.Runtime) {
_parent = this;
SearchBindingSource();
}
}
private void SearchBindingSource()
{
if (_parent != null && _dataBoundControl == null) {
while (_parent.Parent != null) {
_parent = _parent.Parent;
_dataBoundControl = _parent as IDataBound;
if (_dataBoundControl != null) {
if (_dataBoundControl.BindingSource != null) {
_dataBoundControl.BindingSource.DataSourceChanged +=
new EventHandler(DataBoundControl_DataSourceChanged);
}
return;
}
}
// This control or one of its parents has not yet been added to a
// container. Watch for its ParentChanged event.
_parent.ParentChanged += new EventHandler(Parent_ParentChanged);
}
}
void Parent_ParentChanged(object sender, EventArgs e)
{
SearchBindingSource();
}
void DataBoundControl_DataSourceChanged(object sender, EventArgs e)
{
localBindingSource.DataSource = _dataBoundControl.BindingSource.DataSource;
}
}
- 1. Forma correcta de desvincular un BindingSource de un DataGridView
- 2. desvinculando bindingsource
- 3. Capturar eventos KeyDown en un UserControl
- 4. Heredar de un UserControl en WPF
- 5. ¿Cómo puedo establecer un registro actual de BindingSource como nulo?
- 6. ¿Cómo puede un UserControl de WPF heredar un UserControl de WPF?
- 7. Cuándo debe extraer un UserControl en WPF
- 8. Cómo usar un ContextMenu UserControl en WPF?
- 9. DataGridView bloqueado en un UserControl heredado
- 10. ¿Necesito un BindingSource AND a BindingList para WinForms DataBinding?
- 11. ¿Cuándo debo usar un UserControl en lugar de una página?
- 12. Representación gráfica de un web UserControl
- 13. Propiedad de Custom ItemsSource para un UserControl
- 14. ¿Cómo creo un estilo dentro de un UserControl de WPF?
- 15. Excepciones BindingSource y Cross-Thread
- 16. .NET BindingSource Referencia de sintaxis de filtro
- 17. wpf problema al usar propiedades de dependencia en un UserControl
- 18. Enlace de datos a un UserControl en WPF
- 19. Llamar a un método de UserControl en MVVM
- 20. EF en un UserControl no puede ver la aplicación.config?
- 21. WPF ¿Cómo obtener un UserControl para heredar un botón?
- 22. Propiedad del texto en un UserControl en C#
- 23. DataGridView Filtrar un BindingSource con una lista de objetos como DataSource
- 24. Cómo poner un UserControl en Visual Studio toolbox
- 25. Permitir cualquier propiedad/atributo en un servidor/usercontrol
- 26. ¿Cómo agregar un evento a UserControl en C#?
- 27. Las imágenes incrustadas no se muestran cuando en un UserControl
- 28. UserControl equivalente en MVC3?
- 29. INotifyPropertyChanged en UserControl
- 30. Cargar UserControl en TabItem
Quizás exponer su propiedad de objeto BindingSource.DataSource escribiendo una propiedad que llamaría DataSource, y esto establecería la propiedad BindingSource.DataSource de su formulario. De lo contrario, intente explicar con más detalle lo que desea hacer o dar un ejemplo concreto que pueda ayudarnos a comprender mejor. Todavía lo tengo un poco borroso cuando lo leo. ¿Desea configurar el DataSource en tiempo de diseño? ¿Desea exponer las propiedades de BindingSource en la ventana de Propiedades? ¿Desea vincular los controles de UserControl a un DataMember específico de su BindingSource 'n change on design? –
Quizás podría aceptar la respuesta que los demás le dieron a su pregunta. Creo que esta sería una buena forma de agradecer a aquellos que se tomaron este tiempo para responder y ayudarlo, ya sea que ayudaran o no, se tomaron este tiempo para usted. –
Utilice nombres completos cuando se refiera a objetos y propiedades. Sea específico, proporcione algún código o ejemplos simples. No espere de nosotros entender un contexto perdido. – profimedica