I have a problem with the UltraGrid control from Infragistics. I have created a ultracombobox with a few values in it:
UltraCombo ultraComboPaneel = new UltraCombo();
ultraComboPaneel.DataSource = articleList;
ultraComboPaneel.ValueMember = "ArticleID";
ultraComboPaneel.DisplayMember = "Name";
Now I have an UltraGrid, and I want to put the ultraCombo in a cell so I can choose one of the items of the ultracombo as a cell value. I tried it both in code and in the ultragrid designer but i can't seem to find a way to do it.
Any of you got an idea? More information can be provided if needed
Edit:
I found something like
UltraGridColumn ugc = ultraGridTypePaneel.DisplayLayout.Bands[0].Columns.Add("combo");
ultraGridTypePaneel.DisplayLayout.Bands[0].Columns["combo"].EditorControl = ultraComboPaneel;
I feel I'm on the right way but it is still not showing on the screen...
The UltraCombo provides a great deal of functionality. If all you need is the ability to choose an item from a list, you might find the grid's ValueLists provide a better solution.
Here's some code to get you started:
private void myGrid_InitializeLayout(object sender, Infragistics.Win.UltraWinGrid.InitializeLayoutEventArgs e)
{
const string colorValueList = #"ColorValueList";
if (!e.Layout.ValueLists.Exists(colorValueList))
{
ValueList svl = e.Layout.ValueLists.Add(colorValueList);
svl.ValueListItems.Add(1, "Red");
svl.ValueListItems.Add(2, "Green");
svl.ValueListItems.Add(3, "Blue");
}
e.Layout.Bands[0].Columns["Color"].ValueList = e.Layout.ValueLists[colorValueList];
}
You could find at the link below some approaches that you could use to put a DropDown into a UltraGrid cell:
http://devcenter.infragistics.com/Support/KnowledgeBaseArticle.aspx?ArticleID=7841
Going back to your current code snippet - you are almost there:
First you should set the binding context of your UltraCombo to the BindingContext of the form the your UltraCombo will be used like:
ultraComboPaneel.BindingContext = this.BindingContext;
Please note that setting binging context should happen prior setting your control to be EditorControl. One more thing that I noticed is that the property currently is changed to EditorComponent so I believe that you are using older version of the Infragistics components. However you should still be able to use the very same approach. I have created small code snippet showing the above with code:
public partial class Form1 : Form
{
UltraCombo uc;
public Form1()
{
InitializeComponent();
DataTable dt = new DataTable();
dt.Columns.Add("Int", typeof(int));
dt.Rows.Add(1);
dt.Rows.Add(1);
dt.Rows.Add(1);
DataTable dtt = new DataTable();
dtt.Columns.Add("Int", typeof(int));
dtt.Rows.Add(2);
dtt.Rows.Add(2);
dtt.Rows.Add(2);
uc = new UltraCombo();
uc.BindingContext = this.BindingContext;
uc.DataSource = dtt;
ultraGrid1.DataSource = dt.DefaultView;
}
private void ultraGrid1_InitializeLayout(object sender, Infragistics.Win.UltraWinGrid.InitializeLayoutEventArgs e)
{
e.Layout.Bands[0].Columns[0].EditorComponent = uc;
}
}
Hope this helps.
I use the Ultra Dropdown instead.
dim udd As UltraDropDown
udd = New UltraDropDown
With udd
'add data binding or value list items here
End With
Me.ultragrid.DisplayLayout.Bands(0).Columns("Column Name").ValueList = udd
The key is the last line that assigns the "Value List" of the ultra grid column to the Drop down control.
Related
I have 2 forms: The first form has textboxes that display different task names and times spent on each task. The second form has a datagridView. Using:
public void DataTableTest()
{
//Create DataTable
DataTable dt = new DataTable();
//Add Columns
dt.Columns.Add("Task Name", typeof(string));
dt.Columns.Add("Time Worke (HH:mm:ss)", typeof(string));
//Add Rows
dt.Rows.Add();
dataGridView1.DataSource = dt;
}
I am able to get the data table layout the way I want. My issue is, I want to pull the textbox.text from Form1 to populate the [0][0] cell of the data table. Something like:
//Add Rows
dt.Rows.Add();
dt.Rows[0][0] = Form1.tasktextbox1.text;
dataGridView1.DataSource = dt;
But this is not working. I am getting the following from my error list when I try to start the program:
'TaskTracker.Form1.TaskTextBox1' is inaccessible due to its protection level.
Thank you in advance for the assistance. If you have any questions ask, first time posting and new to programming.
The error describes itself: TaskTextBox1 is a private member of Form1 and you cannot call it on another class. Add a property to Form1:
Public string task1text { get { return this.textbox1.text; }}
and then use it on the other form:
dt.Rows[0][0] = Form1.task1text;
I was able to complete this task with:
public static string task1text;
public void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
task1text = TaskTextBox1.Text;
ReportForm RF = new ReportForm();
RF.Show();
}
on form1 and using Roozbeh's suggestion on the second form:
dt.Rows[0][0] = Form1.task1text;
Thank you all for your assistance. Slowly figuring it out! :)
I am new to using the telerik tools for winforms and I was wondering if anyone could help me to find the best way so that the client can add a new row on the radgrid and for it to show this change on the data source.
so far I have the radgrid set up so that the client can add a new row. I just need to bind it to the data source.
private void radGridView1_Click(object sender, EventArgs e)
{
this.radGridView1.AllowEditRow = false;
this.radGridView1.AllowAddNewRow = true;
this.radGridView1.AllowDeleteRow = false;
this.radGridView1.AddNewRowPosition = Telerik.WinControls.UI.SystemRowPosition.Top;
this.radGridView1.MasterTemplate.AddNewBoundRowBeforeEdit = true;
radGridView1.EnableAlternatingRowColor = true;
}
Have a look at the UserAddedRow event for RadGridView. This is fired after the user added a new row to the grid. You could then add the new entries to a source list or data table.
List<Foo> _lSource = new List<Foo>();
DataTable _tSource = new DataTable();
private void radGridView1_UserAddedRow(object sender, GridViewRowEventArgs e)
{
Foo foo = new Foo();
foo.Col1 = e.Row.Cells["col1"].Value.ToString();
foo.Col2 = e.Row.Cells["col2"].Value.ToString();
_lSource.Add(foo);
_tSource.Rows.Add(e.Row.Cells["col1"].Value.ToString(), e.Row.Cells["col2"].Value.ToString());
}
I added both possibilities in the same code snippet. Just choose one (list or table). I just created a random class to show you an example. You can create your own classes and name the properties as you want. Just note that the column (col1 and col2 in my example) must exist, otherwise you'll get a NullReferenceException. If you're using DataTable you have to add the columns once before adding rows.
_tSource.Columns.Add("col1");
_tSource.Columns.Add("col2");
I also recommend not to update the RadGridView properties on a click event of RadGridView. Because it is enough to set those properties once. Now you set them every time you click in your grid view. Either move them to the Load event of your form or set it directly in designer properties.
private void Form_Load(object sender, EventArgs e)
{
radGridView1.AllowEditRow = false;
radGridView1.AllowAddNewRow = true;
radGridView1.AllowDeleteRow = false;
radGridView1.AddNewRowPosition = Telerik.WinControls.UI.SystemRowPosition.Top;
radGridView1.MasterTemplate.AddNewBoundRowBeforeEdit = true;
radGridView1.EnableAlternatingRowColor = true;
}
RadGridView supports data binding to variety of data sources and CRUD operation will be handled for you automatically. Here you can find information on the supported data sources: Telerik UI for WinForms Documentation
And here is how to bind to a DataTable, where all CRUD operations work out of the box
RadGridView radGridView1 = new RadGridView();
this.Controls.Add(radGridView1);
radGridView1.Dock = DockStyle.Fill;
DataTable table = new DataTable();
table.Columns.Add("col1");
table.Columns.Add("col2");
table.Rows.Add("value1", "value1");
table.Rows.Add("value2", "value2");
radGridView1.DataSource = table;
Here is also a design time tutorial.
I have a DataGridView tied to a DataTable source. Among the data on the elements in the table is a Guid which I want to remain hidden. (It's used internally for reference, but should not be displayed.) The code I'm using to create the table is as follows:
private DataTable mEntities = new DataTable();
private System.Windows.Forms.DataGridView EntitiesGridView;
These are declared elsewhere, just showing here for reference.
private void BuildEntityTable()
{
mEntityTable.Columns.Add("id", typeof(Guid));
mEntityTable.Columns.Add("Name", typeof(string));
... (some other columns)
foreach (Foo foo in mEntities)
{
DataRow row = mEntityTable.NewRow();
row["id"] = foo.id;
row["Name"] = foo.Name;
... (rest of data)
mEntityTable.Rows.Add(row);
}
DataColumn[] entityKeys = new DataColumn[1];
entityKeys[0] = entityTable.Columns["id"];
mEntityTable.PrimaryKey = entityKeys;
EntitiesGridView.DataSource = mEntityTable.DefaultView;
EntitiesGridView.Columns["id"].visible = false;
}
So far so good. The table is created, and there's no visible "id" column. However, if I later add a new object to the table, we run into trouble. The code is almost the same:
void AddNewObject(object sender, MyArgs e)
{
Foo foo = e.Foo;
lock (mEntities)
{
mEntities.Add(foo);
}
lock (mEntityTable)
{
DataRow row = mEntityTable.NewRow();
row["id"] = foo.id;
row["Name"] = foo.Name;
... (rest of data)
mEntityTable.Rows.Add(row);
}
}
For some reason, this makes the "id" column come back. I've tried copying the EntitiesGridView.Columns["id"].visible = false; line from the previous code, but it does no good. Nothing I do after this point will make that column go away and stay gone. Any clues what I'm missing?
just write this line
datagridview1.Columns[0].visible = false;
call this event in your form_load()
private void dgv_DataBindingComplete(Object sender, DataGridViewBindingCompleteEventArgs e)
{
DataGridView dgv = (DataGridView)sender;
dgv.Columns[3].Visible = false;
}
I have also encountered this problem, but found that you can make your datagridview changes at design time and then save the project. Run the application, then quit from the application. The dgv on the design form has now automatically changed its display. Close the form and reopen it and you will see that the columns you originally included/excluded are returned. No additional code is required for this fix.
This will be a stupid question but I have a datagridview with a BindingSource as datasource.
The bindingSources.Datasource is a own BindingList with sort support. All this works.
But when a record will be inserted in the sorted list, then it will placed at the end of the datagridiview. After a refresh (example with the mouse click), the record will be placed on the right place.
So, I think that I forget something to implementat or call to ensure that the inserted record will be displayed directy on the right place of the datagridview.
Who can help me with a tip.
Thanks.
I have this working with the following code.
Please excuse the rough code - I'm just showing the key pieces, but I can provide a more complete example if you need.
I have a SortableBindingList _names which is bound to my DataGridView. Then on my form I have a button, with a new names added in the Click even handler. This is working fine to add the name kevin between joe and pete.
private SortableBindingList<Names> _names;
public Form1()
{
InitializeComponent();
_names = new SortableBindingList<Names>();
_names.Add(new Names() { Name = "joe" });
_names.Add(new Names() { Name = "pete" });
DataGridViewTextBoxColumn col1 = new DataGridViewTextBoxColumn();
col1.DataPropertyName = "Name";
dataGridView1.Columns.Add(col1);
dataGridView1.DataSource = _names;
}
private void button1_Click(object sender, EventArgs e)
{
_names.Add(new Names(){Name = "kevin"});
dataGridView1.Sort(dataGridView1.Columns[0], ListSortDirection.Descending);
}
public class Names
{
public string Name { get; set; }
}
So the key thing is that I sort my dataGridView after adding to the list.
I could have also provided an IComparer in my .Sort() call - the default comparer is just comparing on .ToString()
Interestingly, in my example, the following also works, when inserting the item:
private void button1_Click(object sender, EventArgs e)
{
//_names.Add(new Names(){Name = "kevin"});
_names.Insert(1, new Names() { Name = "kevin" });
// dataGridView1.Sort(dataGridView1.Columns[0], ListSortDirection.Descending);
}
Simply inserting the item at the right place is enough to make the grid display the list sorted correctly. I'm using the same SortableBindingList as you, the one shown at MartinWilley.com.
Could your problem be that you are adding rather then inserting?
Maybe try handling the BindingSource.ListChanged event?
This code snippet works very well, and fast enough for most purposes...
int iColNumber = 3; //e.g., sorting on the 3rd column of the DGV
MyBindingSource.DataSource = MyBindingList.OrderByDescending(o => o.GetType().GetProperty(MyDataGridView.Columns[iColNumber].Name).GetValue(o));
I have a List and a Button. When the Lists Count == 0, I would like the button Visibility to = false.
How do I do this using Data Binding?
Thanks in advance,
Added
I have asked this so that I can try to avoid checking the Count on the list in code every time I add or remove an item to or from the list. But if there is no solution then I will continue to do it that way.
Create a DTO (Data Transfer Object) that exposes all your data that you intend to bind to UI elements. Create a property in the DTO (with an appropriate name):
public bool ButtonVisible
{
get { return myListCount != 0; }
}
Add a BindingSource to your form and set it's DataSource to your DTO type.
Click on the Button, goto Properties. Expand the DataBindings node, and click Advanced.
Scroll down the list in the left hand pane, and select Visible. Set it's binding to your property exposed vis the BindingSource..
The General Answer
Write an event handler and register it with your list-control's bindings object
A Specific Example
class MyForm : Form {
protected Button myButton;
BindingSource myBindingSource;
DataGridView dgv;
public MyForm(List someList) {
myBindingSource = new BindingSource();
dgv = new DataGridView();
this.myButton = new Button();
this.Controls.Add(myButton);
this.Controls.Add(dgv);
myBindingSource.DataSource = someList;
dgv.DataSource = myBindingSource;
dgv.DataSource.ListChanged += new ListChangedEventHandler (ListEmptyDisableButton);
}
protected void ListEmptyDisableButton (object sender, ListChangedEventArgs e) {
this.myButton.Visible = this.dgv.RowCount <= 0 ? false : true;
}
}
PS - I'd vote down the favorite answer. A Data Transfer Object (DTO) misses the whole point and functionality of .NET Binding architechture
As the question is currently worded, it doesn't sound like it has anything to do w/ DataBind.
If we have a list -- doesn't matter whether it's populated via code or bound to a data source -- we can set the button's visibility based on the count.
e.g.
List<string> somelist = new List<string>();
somelist.Add("string1");
somelist.Add("string2");
Button1.Visible = somelist.Count > 0 ? true : false;
I think you want to be using the CurrencyManager and the BindingContext of the control.
http://www.akadia.com/services/dotnet_databinding.html#CurrencyManager