I create a DataGridView as follows
private void IniciarGV()
{
using (var db = new Entities())
{
var ListaPantallas = (from a in db.PANTALLAS
select a).ToList();
if (ListaPantallas != null)
{
gvPermisos.DataSource = ListaPantallas;
gvPermisos.Columns["idPantalla"].Visible = false;
gvPermisos.Columns["nombrepantalla"].HeaderText = "Nombre";
//gvPermisos.Columns.Add(new DataGridViewCheckBoxColumn());
DataGridViewCheckBoxColumn checkBoxColumn = new DataGridViewCheckBoxColumn();
checkBoxColumn.HeaderText = "Seleccione";
checkBoxColumn.Width = 50;
checkBoxColumn.Name = "checkBoxColumn";
gvPermisos.Columns.Insert(0, checkBoxColumn);
//gvPermisos.EndEdit();
}
db.Dispose();
}
}
After that a i retrieve the privileges with the same method linq
var TraerPermisos = (from a in db.PERMISOS
where a.IDUSUARIO == UsuarioEditar.idUsuario
select a).ToList();
After i go through the gridview to match the privileges with the ids that i wanted to check so the user can edit them, but for some reason they always appear unmarked
so far this is what i encounter in every forum or google, but it doesnt seem to work
foreach (PERMISOS item in TraerPermisos)
{
foreach (DataGridViewRow row in gvPermisos.Rows)
{
var ValorPermisoEnGV = Convert.ToBoolean(row.Cells["checkBoxColumn"].Value);
var ValorPantalla = decimal.Parse(row.Cells["idPantalla"].Value.ToString());
if (ValorPantalla == item.IDPANTALLA)
{
row.Cells["checkBoxColumn"].Value = true;
}
}
}
this what my form looks like
I load the privileges on start
public ManejarUsuario()
{
InitializeComponent();
IniciarComboBox();
IniciarGV();
if (UsuarioEditar.idUsuario != 0)
{
CargarDatos();
btnCrearUsuario.Text = "Editar";
CargarPrivilegios();
}
}
Sorry about the long post, i've tried so many options but none seems to work
Life would be a lot easier if you just put a Boolean in the data driving the grid. First, let's make a holder class for your info
class Perms{
public int IdPantalla { get; set; }
public string NombrePantalla { get; set; }
public bool HasPermission { get; set; }
}
Then let's have the query produce a list of these instead:
//get all the IDPANTALLA this user has and put in a hash set
var TraerPermisos = (from a in db.PERMISOS
where a.IDUSUARIO == UsuarioEditar.idUsuario
select a.IDPANTALLA).ToHashSet();
//make a list of objects that includes a bool of whether the user has that permission
//note you should have this be a class level variable for ease of use later/elsewhere
ListaPantallas = (from a in db.PANTALLAS
select new Perms {
IdPantalla a.IdPantalla,
HasPermission = TraerPermisos.Contains(a.idPantalla) ,
NombrePantalla = a.nombrepantalla
}).ToList();
Then set up the grid:
gvPermisos.DataSource = ListaPantallas;
gvPermisos.Columns["IdPantalla"].Visible = false;
gvPermisos.Columns[ "NombrePantalla"].HeaderText = "Nombre";
gvPermisos.Columns[ "HadPermission"].HeaderText = "Seleccione";
The grid will find the bool property in the list and wire it up for you as a check column. It doesn't need you to make a column for it. Anything you tick is then stored in the underlying list as a true/false and you can eg foreach(var x in ListaPantallas) if(x.HasPermission...
When manipulating data in a DGV that is bound to a data source, manipulate the source. Also consider to make Perms implements INotifyPropertyChanged (and consider switching to using a binding list)
Related
cant select combo item by value after its passed to form. Comb is populated properly i get all the customers displayed by Text.
public OrderViewerForm(string orderId)
{
InitializeComponent();
PopulateCustomerCombobox();
PopulateForm(orderId);
PopulateProductsTable();
}
private void PopulateForm(string orderId)
{
OrderModel order = db.LoadOrder(orderId);
List<ProductsOrderedModel> productsOrdered = db.ProductsOrdered_Load(orderIdValue.Text);
orderIdValue.Text = order.Id.ToString();
customerIdValue.Text = order.CustomerId.ToString();
customerIdCombo.SelectedValue = order.CustomerId;
}
private void PopulateCustomerCombobox()
{
customerIdCombo.Items.Clear();
List<CustomerModel> customer = db.CustomerGet_All();
foreach (CustomerModel c in customer)
{
customerIdCombo.DisplayMember = "Text";
customerIdCombo.ValueMember = "Value";
customerIdCombo.Items.Add(new { Text = c.FullInfo, Value = c.Id });
}
}
At the end order.CustomerId is set properly but customerIdCombo.SelectedValue stays null. What am I doing wrong?
I would suggest switching to databinding here. Your foreach looks weird by the way.
private void PopulateCustomerCombobox()
{
customerIdCombo.DisplayMember = "Text";
customerIdCombo.ValueMember = "Value";
customerIdCombo.DataSource = db.CustomerGet_All().Select(c=> new { Text = c.FullInfo, Value = c.Id});
}
Thinking about it you may want to drop the hole anonymous type thing. why not simply bind the list you get from CustomerGet_All?
I need help on part of this code. I'm using a checkbox column in my DataGridView control. When I retrieve my data record, if a value exists then the checkbox should be checked, and if not it should remain unchecked. How to I accomplish that on a DataGridView with this kind of logic?
using (DataContext dtContext = new DataContext())
{
var query = (from i in dtContext.materialTBheader where i.proj == Proj_id select i);
foreach (var r in query)
{
if (!string.IsNullOrEmpty(r.materialheader_id.ToString()))
{
string[] row = { r.materialheader_id.ToString(), r.materialname, r.description, string.Format("{0:n2}", r.totalAmount), GetCount(r.materialname, txtMainProjectHeader_id, Convert.ToDecimal(r.totalAmount)), "", -- cell checkbox if record exist true checked if not false uncheck };
dGVMaterialHeaderList.Rows.Add(row);
}
}
}
It dosen't need to add your rows by foreach, use DataSource Property
Suppose you have a List of Person and you want to show in dataGridview, you have to option
1)add your column to data grid in visual studio properties window
2)add your column with coding
then map your data to grid
here is an simple example to help yo
public class Person
{
public int Id { get; set; }
public string LastName { get; set; }
public bool Married { get; set; }
}
private void Form1_Load(object sender, EventArgs e)
{
//your data from ef
var myData = new List<Person>
{
new Person{Id=1,LastName="A1",Married =true},
new Person{Id=1,LastName="A2",Married =false},
new Person{Id=1,LastName="A3",Married =true},
};
//your columns
var idColumn = new System.Windows.Forms.DataGridViewTextBoxColumn
{
Name = "Id",
HeaderText = "Id",
DataPropertyName = "Id"
};
var lastNameColumn = new System.Windows.Forms.DataGridViewTextBoxColumn
{
Name = "LastName",
HeaderText = "LastName",
DataPropertyName = "LastName"
};
var marriedColumn = new System.Windows.Forms.DataGridViewCheckBoxColumn
{
Name="Married",
HeaderText="Married",
DataPropertyName= "Married"
};
// add your columns to grid
dGVMaterialHeaderList.Columns.Add(idColumn);
dGVMaterialHeaderList.Columns.Add(lastNameColumn);
dGVMaterialHeaderList.Columns.Add(marriedColumn);
dGVMaterialHeaderList.AutoGenerateColumns = false;
//bind your data
dGVMaterialHeaderList.DataSource = myData;
}
In your case the answer is something like below:
using (DataContext dtContext = new DataContext())
{
var query = (from i in dtContext.materialTBheader where i.proj == Proj_id select i).ToList();
var gridData = query.Select(r=>new
{
materialheader_id = r.materialheader_id.ToString(),
r.materialname,
r.description,
totalAmount = string.Format("{0:n2}", r.totalAmount),
Count = GetCount(r.materialname, txtMainProjectHeader_id, Convert.ToDecimal(r.totalAmount)),
isExist = !string.IsNullOrEmpty(r.materialheader_id.ToString())?true:false
}).ToList();
dGVMaterialHeaderList.DataSource = gridData;
}
I don't know your data structure but I know this is not best approach you choose
I hope this can help you
I am using ObjectListView to display information regarding virtual machines and each virtual machine has a different set of drives attached to it. During my data gathering, I get all of the info and store it in a Disk_Drive object with the properties that I care for (size,serial,usage,etc), now I want to dynamically create the columns and then bind the data using AddObjects. How would I do this?
I am not sure what the aspect getter should be in this scenario as it will not be unique, how can I handle this?
public void GenerateColumns(Model.HyperVTools.VMInfo vmObject)
{
objectListView2.Columns.Clear();
objectListView2.Items.Clear();
List<OLVColumn> columnsList = new List<OLVColumn>();
OLVColumn vmhostnameColumn = new OLVColumn("Hostname", "Host");
//vhd columns
foreach (var disk in vmObject.DisksList)
{
string text = string.Format("{0};{1}GB;{2}GB;", disk.Path, disk.SizeReadable,
disk.MaxVHDSizeReadable);
disk.FormattedVHDInfo = text;
OLVColumn diskColumn = new OLVColumn("Attached VHD", "FormattedVHDInfo");
columnsList.Add(diskColumn);
}
columnsList.Add(vmhostnameColumn);
objectListView2.Columns.AddRange(columnsList.Cast<System.Windows.Forms.ColumnHeader>().ToArray());
objectListView2.AddObject(vmObject);
}
Try this:
DataTable dtInput = new DataTable();
dtInput = dsAnalystPage.Tables[0];
foreach (DataColumn cl in dtInput.Columns)
{
BrightIdeasSoftware.OLVColumn aNewColumn = new BrightIdeasSoftware.OLVColumn();
aNewColumn.Name = cl.ColumnName;
aNewColumn.Text = cl.ColumnName;
if (aNewColumn.Text == "ASF_Code" || aNewColumn.Text == "ASD_SheetCode" || aNewColumn.Text == "ASD_SheetName")
{
aNewColumn.Width = 0;
aNewColumn.IsVisible = false;
}
OLV.AllColumns.Add(aNewColumn);
OLV.RebuildColumns();
}
Try resetting the control.
OLV.Reset();
I have a datagridview in my form. It fills by selecting country with cities of country.I have set the property (AllowUsersToAddRow = True)
but when i run my project user can't add or edit or delete any row.I checked it.It is not readonly(readonly = false) and It is enable (Enabled = true)
What's the problem?
Code of fill datagridview:
private void cmbCountryValues_SelectedIndexChanged(object sender, EventArgs e)
{
dgvCityValues.Enabled = cmbCountryValues.SelectedIndex>=0;
if (!dgvCityValues.Enabled)
{
dgvCityValues.DataSource = null;
return;
}
int CountryId = int.Parse(cmbCountryValues.SelectedValue.ToString());
dgvValues.DataSource = from record in Program.dal.Cities(CountryId) select new { record.City};
}
If you find this question useful don't forgot to vote it.
To give a simplified example, if I do the equivalent of your query, such as:
var cities = new City[] { new City("New York","NY"), new City("Sydney","SY"), new City("London","LN") };
dataGridView.DataSource = cities;
I get the same result as you - no option to add new rows, but if I change to BindingList<T> and set this to AllowNew it all works:
var cities = new City[] { new City("New York","NY"), new City("Sydney","SY"), new City("London","LN") };
var citiesBinding = new BindingList<City>(cities);
citiesBinding.AllowNew = true;
dataGridView.DataSource = citiesBinding;
EDIT - with a solution for your particular example:
private class City
{
public string Name { get; set; }
}
private void cmbCountryValues_SelectedIndexChanged(object sender, EventArgs e)
{
dgvCityValues.Enabled = cmbCountryValues.SelectedIndex >= 0;
if (!dgvCityValues.Enabled)
{
dgvCityValues.DataSource = null;
return;
}
int CountryId = int.Parse(cmbCountryValues.SelectedValue.ToString());
var queryResults = from record in Program.dal.Cities(CountryId) select new City { Name = record.City };
var queryBinding = new BindingList<City>(queryResults.ToList());
queryBinding.AllowNew = true;
dgvValues.DataSource = queryBinding;
}
Note that a) I had to change the anonymous type in the query select into a concrete type City and also change the IEnumerable<T> returned by Linq query to an IList<T> compatible type to create the BindingList<T>. This should work, however :)
In this question, Add a column to IEnumerable in C#, I got the following code:
var db = Database.Open("LOS");
var ie = db.Query(sqlAssignments);
// make a new ie2 that has an extra calculated field
var ie2 = processes.Select( e => new { e.ACCT, e.RefID, color = e.RefID + 9000000 });
var grid = new WebGrid(ie2.ToList(), rowsPerPage : 50, ajaxUpdateContainerId : "grid" );
The data correctly shows up, however the grid no longer sorts. It sorts fine if you pass ie, instead of ie2. It has the problem if I do the ToList() or not. Obviously there's some difference between ie and ie2. Here's the GetType for ie:
System.Collections.ObjectModel.ReadOnlyCollection`1[System.Object]
and for ie2:
System.Linq.Enumerable+WhereSelectEnumerableIterator`2[System.Object,<>f__AnonymousType0`10[System.Object,System.Object,System.Object,System.Object,System.Object,System.Object,System.Object,System.Object,System.Object,System.Object]]
What should I do to ie2 to make it work with WebGrid and sort correctly?
Try to create a type for ie2 instead of using an anonymous type, like:
var ie2 = processes.Select( e =>
new MyNewType { ACCT = e.ACCT, RefID = e.RefID, Color = e.RefID + 9000000 }
);
Where the new type would be:
class MyNewType {
public string ACCT { get; set }
public int RefID { get; set }
public int Color { get; set }
}