c# - raya - operaciones con numeros complejos
¿Es posible vincular propiedades de tipo complejo a una cuadrícula de datos? (9)
Podría intentar vincular propiedad DataGrid a Maker.Name
¡Espero ayudarte!
¿Cómo voy a vincular el siguiente objeto, Coche, a una vista en cuadrícula?
public class Car { long Id {get; set;} Manufacturer Maker {get; set;} } public class Manufacturer { long Id {get; set;} String Name {get; set;} }
Los tipos primitivos se enlazan fácilmente, pero no he encontrado forma de mostrar nada para Maker. Me gustaría que muestre el Nombre del fabricante. ¿Es posible?
¿Cuál sería una forma de hacerlo? ¿Tendría que almacenar ManufacturerId en el auto también y luego configurar un lookupEditRepository con la lista de fabricantes?
Sí, puede crear un TypeDescriptionProvider para lograr un enlace anidado. Aquí hay un ejemplo detallado de un blog de MSDN:
Simplemente use una Lista y configure el DataMember en la cadena "Maker.Name" y si desea que DataKeyField use la ID del automóvil, simplemente configúrelo como "ID".
dataGrid.DataSource = carList;
dataGrid.DataMember = "Maker.Name";
dataGrid.DataKeyField = "ID";
dataGrid.DataBind();
Sé que funciona en el control de repetidor, al menos ...
public class Manufacturer
{
long Id {get; set;}
String Name {get; set;}
public override string ToString()
{
return Name;
}
}
Anula el método de cadena.
La forma en que me acerqué a esto en una aplicación reciente fue crear mis propias clases DataGridViewColumn y DataGridViewCell heredando de una de las existentes, como DataGridViewTextBoxColumn y DataGridViewTextBoxCell.
Dependiendo del tipo de celular que desee, puede usar otros como Button, Checkbox, ComboBox, etc. Simplemente eche un vistazo a los tipos disponibles en System.Windows.Forms.
Las celdas tratan con sus valores como objetos, por lo que podrás pasar tu clase de Auto al valor de la celda.
Anular SetValue y GetValue le permitirá tener cualquier lógica adicional que necesite para manejar el valor.
Por ejemplo:
public class CarCell : System.Windows.Forms.DataGridViewTextBoxCell
{
protected override object GetValue(int rowIndex)
{
Car car = base.GetValue(rowIndex) as Car;
if (car != null)
{
return car.Maker.Name;
}
else
{
return "";
}
}
}
En la clase de columna, lo principal que debe hacer es configurar CellTemplate en su clase de celda personalizada.
public class CarColumn : System.Windows.Forms.DataGridViewTextBoxColumn
{
public CarColumn(): base()
{
CarCell c = new CarCell();
base.CellTemplate = c;
}
}
Al usar estas Columnas / Celdas personalizadas en DataGridView, le permite agregar mucha funcionalidad extra a su DataGridView.
Los usé para alterar el formato mostrado anulando GetFormattedValue para aplicar formato personalizado a los valores de cadena.
También hice una anulación en Paint para poder hacer resaltado de celda personalizado dependiendo de las condiciones de valor, alterando las celdas Style.BackColor a lo que quería según el valor.
Si desea exponer propiedades anidadas específicas como objetivos vinculantes, entonces la respuesta de Ben Hoffstein ( http://blogs.msdn.com/msdnts/archive/2007/01/19/how-to-bind-a-datagridview-column- to-a-second-level-property-of-a-data-source.aspx ) es bastante bueno. El artículo al que se hace referencia es un poco obtuso, pero funciona.
Si solo desea vincular una columna a una propiedad compleja (por ejemplo, Fabricante) y anular la lógica de representación, haga lo que recomienda ManiacXZ, o simplemente la subclase BoundField y proporcione una implementación personalizada de FormatDataValue (). Esto es similar a anular ToString (); obtienes una referencia de objeto y devuelves la cadena que deseas mostrar en tu cuadrícula.
Algo como esto:
public class ManufacturerField : BoundField
{
protected override string FormatDataValue(object dataValue, bool encode)
{
var mfr = dataValue as Manufacturer;
if (mfr != null)
{
return mfr.Name + " (ID " + mfr.Id + ")";
}
else
{
return base.FormatDataValue(dataValue, encode);
}
}
}
Simplemente agregue un ManufacturerField a su grilla, especificando "Manufacturer" como el campo de datos, y listo.
Supongo que podrías hacer lo siguiente:
public class Car
{
public long Id {get; set;}
public Manufacturer Maker {private get; set;}
public string ManufacturerName
{
get { return Maker != null ? Maker.Name : ""; }
}
}
public class Manufacturer
{
long Id {get; set;}
String Name {get; set;}
}
Aquí hay otra opción que obtuve trabajando:
<asp:TemplateColumn
HeaderText="Maker">
<ItemTemplate>
<%#Eval("Maker.Name")%>
</ItemTemplate>
</asp:TemplateColumn>
Puede ser ASP.NET 4.0 específico, pero funciona como un encanto!
Bueno, muchachos ... Esta pregunta fue publicada, pero encontré una forma bastante agradable y simple de hacerlo utilizando el reflejo en el evento cell_formatting para ir a recuperar las propiedades anidadas.
Va así:
private void Grid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
DataGridView grid = (DataGridView)sender;
DataGridViewRow row = grid.Rows[e.RowIndex];
DataGridViewColumn col = grid.Columns[e.ColumnIndex];
if (row.DataBoundItem != null && col.DataPropertyName.Contains("."))
{
string[] props = col.DataPropertyName.Split(''.'');
PropertyInfo propInfo = row.DataBoundItem.GetType().GetProperty(props[0]);
object val = propInfo.GetValue(row.DataBoundItem, null);
for (int i = 1; i < props.Length; i++)
{
propInfo = val.GetType().GetProperty(props[i]);
val = propInfo.GetValue(val, null);
}
e.Value = val;
}
}
¡Y eso es! Ahora puede usar la sintaxis familiar "ParentProp.ChildProp.GrandChildProp" en DataPropertyName para su columna.