Dropdownlist ID change name - c#

The headline is not good. I don't know how anything better to write in the headline. But here it comes.
I am making a soccerfield with all the different positions. On each position I have a dropdownlist that shows the players in the team.
I made parts of the dropdownlists and came to realised that I was doing it wrong.
try
{
int pos = list[i].positionsID;
if (pos == 1)
{
ddlGoal.Visible = true;
lblGoal.Visible = true;
ddlGoal.DataSource = list1;
ddlGoal.DataValueField = "id";
ddlGoal.DataTextField = "name";
ddlGoal.DataBind();
}
} catch ...
It should only show the position of there are any players on that position. It all works fine... but i have 28 positions, and there for 28 of the above try/catch things.
I want to scale it down, by only making one.
If i let all the dropdownlists have the same name as the postions saved on my database I should be able to make just one. So i have tried that:
try
{
int pos = list[i].positionsID;
if (pos != 0)
{
string ddl = "ddl" + list3[i].positionsNavn.ToString();
ddl.Visible = true;
lblGoal.Visible = true;
ddlGoal.DataSource = list1;
ddlGoal.DataValueField = "id";
ddlGoal.DataTextField = "name";
ddlGoal.DataBind();
}
} catch...
It doesn't work. How do i get hold of the dropdownlist with ID ddlGoalKeeper when i am creating the ID as:
string ddl = "ddl" + list3[i].positionsNavn.ToString();
Any ideas or help??

I think this is what you need. Given the ID of any control you can use
FindControl
http://msdn.microsoft.com/en-us/library/system.web.ui.control.findcontrol.aspx
to get any control in the control tree. You wil need to use it on the naming container that contains the control i.e.
Panel.FindControl(controlID)
or use the recursive version wriiten by a certain Jeff Atwood
http://www.codinghorror.com/blog/2005/06/recursive-pagefindcontrol.html
Alternatively - construct a Dictionary collection will all your dropdowns mapped to IDs and get them for this. Could be more efficient with more setup

Related

How TO Prevent Multiple Entries in my ListBox when selecting Item From a List View

I have a ASP ListView Control that populates data from a SQL Server database, and it is working as designed. I also have a ASP Listbox control that gets populated with the ID and Name from the ListView Control, it is kind of working, that is if I select it it displays as designed, but if I keep selecting the same row from the ListView Control it keeps adding it to the Listbox, this is not what I desire, I would rather it only shows one time no matter how many times I selected the same row from the list view.
This is what I have
protected void distList_SelectedIndexChanging(object sender, ListViewSelectEventArgs e)
{
int rowIndex;
distList.SelectedIndex = e.NewSelectedIndex;
rowIndex = distList.SelectedIndex;
string sapId = distList.DataKeys[rowIndex].Values[0].ToString();
string DistributorName = distList.DataKeys[rowIndex].Values[1].ToString();
string output = sapId + " " + DistributorName;
SAPListBox.Items.Add(output);
}
I am at a stand still as I been at this all day trying many thing just to get nowhere, I I think I might just be missing something.
int rowIndex;
distList.SelectedIndex = e.NewSelectedIndex;
rowIndex = distList.SelectedIndex;
//You might need to change this, to the listbox rather than a listview. Wasn't quite sure which one you wanted.
var txt = rowIndex;
if (!distlist.Items.ContainsKey(txt))
{
string sapId = distList.DataKeys[rowIndex].Values[0].ToString();
string DistributorName = distList.DataKeys[rowIndex].Values[1].ToString();
string output = sapId + " " + DistributorName;
SAPListBox.Items.Add(output);
}
Hopefully this helps, if not. It was my best attempt ^^

DropDownList lose index after PostBack

I have a dropdown which I fill with data from a SQL server.
I fill the dropdown dynamically in the Page_Init() Event.
Depending on the Value, a ListItem is selected.
Now the problem is, that when I select another Item in the dropdown, that after the postback the selection is reset to the first item in the dropdownlist.
This here is a basic version of my code which does not work:
ArrayList AD_Group_Members = ActiveDirectory.GetMemberOfGroup("AD-Group");
ArrayList ListMachines = SQLQuery.Read("Database", "SELECT idVM, RandomString, Computername, Owner, FROM VM ORDER BY Computername");
for (int i = 0; i < ListMachines.Count; i++)
{
String RandomString = ((Hashtable)ListMachines[i])["RandomString"].ToString();
String Owner = ((Hashtable)ListMachines[i])["Owner"].ToString();
DropDownList DropDownList_Owner = new DropDownList();
DropDownList_Owner.ID = "DropDownList_Owner_" + RandomString;
DropDownList_Owner.Width = Unit.Percentage(95);
DropDownList_Owner.AutoPostBack = true;
DropDownList_Owner.EnableViewState = true;
DropDownList_Owner.SelectedIndexChanged += DropDownList_Owner_SelectedIndexChanged;
Div_Test.Controls.Add(DropDownList_Owner);
for (int y = 0; y < AD_Group_Members.Count; y++)
{
ListItem ListItem = new ListItem();
ListItem.Value = Owner;
ListItem.Text = ((Hashtable)AD_Group_Members[y])["GivenName"].ToString() + " " + ((Hashtable)AD_Group_Members[y])["Surname"].ToString();
if (((Hashtable)AD_Group_Members[y])["Username"].ToString().Equals(Owner))
{
ListItem.Selected = true;
}
DropDownList_Owner.Items.Add(ListItem);
}
}
Where is the issue in my code, that it doesn't work but the example.
Thank in Advance
You have to populate your dropdownlist under this condition on pageload.
Because on every post back your ddl is populated again and loses its selected index.
if (!IsPostBack)
{
//PopulateYourDDL here
}
You filled dropdown in Page_Init() which gets called in every postback and refill your dropdown and hence loses selectedindex.So you have to fill your dropdown inside !ispostback block
if (!IsPostBack)
{
//fill your dropdown here
}
I think the you should have unique values for the dropdown. Also as you have duplicate values in data value field the problem is occurring. It is looking for the first match and selecting it. You could try to fabricate the values which you could uniquely identify. Something like below:
COLUMN_NAME DATA_TYPE
a a_decimal
b b_decimal
c c_decimal
d d_int
e e_int
f f_varchar
g g_varchar
h h_varchar
i i_varchar
j j_varchar
Check out this Useful Source!!!
I hope it helps!!! Have a close look at those comments in the accepted answer section !!!
Also avoid using SelectedIndex_Changed() functions while dealing with Dynamically generated Web controls. Bind the DropdownList under Page_Init() or Page_PreInit(). If you want to perform some functions upon DropDownlist Selection Check out this! to determine the WebControl ID which is triggered and then perform an unique function in the Page_PreInit() or Page_Init().

How do I bind a DataGridViewComboBoxColumn to a property/method of an object that returns a list?

I have a custom object with several properties, one of which returns a list. This is the code for the object:
public class SearchResult
{
private int eventId;
private String eventTitle;
private int startDate;
private List<String> tags;
// Properties
public int EventId { get { return this.eventId; } }
public String EventTitle { get { return this.eventTitle; } }
public int StartDate { get { return this.startDate; } }
public List<String> Tags { get { return this.tags; } }
public SearchResult(int eventId, String eventTitle, int startDate, List<String> tags)
{
// Constructor code
}
public List<String> GetTags()
{
return this.tags;
}
}
I also have a DataGridViewComboBoxColumn that I want to bind to the Tags property. Basically, each SearchResult object will be displayed in its own row, and I want the List<String> in the Tags property of each object to be displayed in a ComboBox cell in that row. This is the code I have so far for my DataGridView:
BindingList<SearchResult> results = new BindingList<SearchResult>();
results.Add(new SearchResult(1, "This is a title", 2012, new List<String> { "Tag1", "Tag with a long name1" }));
results.Add(new SearchResult(2, "The quick brown fox", 2012, new List<String> { "Stack", "Overflow" }));
results.Add(new SearchResult(3, "In this tutorial, you create a class that is the type for each object in the object collection. ", 2012, new List<String> { "NYSE", "FTSE" }));
results.Add(new SearchResult(4, "another long piece of title text", -999, new List<String> { "Rabbits", "Chickens" }));
MyDataGrid.AutoGenerateColumns = false;
MyDataGrid.AllowUserToAddRows = false;
MyDataGrid.AllowUserToDeleteRows = false;
MyDataGrid.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.None;
MyDataGrid.BackgroundColor = System.Drawing.SystemColors.Control;
MyDataGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
MyDataGrid.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders;
MyDataGrid.AutoSizeRowsMode = System.Windows.Forms.DataGridViewAutoSizeRowsMode.DisplayedCells;
MyDataGrid.DefaultCellStyle.WrapMode = DataGridViewTriState.True;
DataGridViewTextBoxColumn eventIdColumn = new DataGridViewTextBoxColumn();
eventIdColumn.DataPropertyName = "EventId";
eventIdColumn.HeaderText = "Event ID";
eventIdColumn.ReadOnly = true;
eventIdColumn.Width = 84;
DataGridViewTextBoxColumn eventTitleColumn = new DataGridViewTextBoxColumn();
eventTitleColumn.DataPropertyName = "EventTitle";
eventTitleColumn.HeaderText = "Event Title";
eventTitleColumn.ReadOnly = true;
eventTitleColumn.Width = 368;
DataGridViewTextBoxColumn startDateColumn = new DataGridViewTextBoxColumn();
startDateColumn.DataPropertyName = "StartDate";
startDateColumn.HeaderText = "Start Date";
startDateColumn.ReadOnly = true;
startDateColumn.Width = 130;
//I think I need to insert the code for the tags column here, but I'm not sure
MyDataGrid.Columns.Add(eventIdColumn);
MyDataGrid.Columns.Add(eventTitleColumn);
MyDataGrid.Columns.Add(startDateColumn);
//MyDataGrid.Columns.Add(tagsColumn);
MyDataGrid.DataSource = results;
I derived this code from a tutorial I found online, and it works perfectly.
I've been trying to bind the Tags property of SearchResult to a DataGridViewComboBoxColumn, but I'm not sure how. I've been looking at this question, which provides this code:
column.DataPropertyName = "Foo";
column.DisplayMember = "SomeNameField";
column.ValueMember = "Bar"; // must do this, empty string causes it to be
// of type string, basically the display value
// probably a bug in .NET
column.DataSource = from foo in Foo select foo;
grid.DataSource = data;
The reason I'm having trouble is because of a few nuances of the linked question that I don't understand.
According to the documentation and the linked question, DisplayMember should be linked to the property that "contains a description of the instance", but since SearchResult objects are added dynamically and don't have any description associated with them, should I just leave it blank?
ValueMember is giving me similar problems, since I'm unsure what to put even after reading its documentation.
In the linked question, the accepted answer binds the entire datagrid at once using LINQ. Is that how I should be doing this? I'm not sure how to modify that code for my situation, but I thought it would be something along these lines.
:
tagsColumn.DataPropertyName = "Tags";
tagsColumn.DisplayMember = ""; // I'm unsure of what to put here
tagsColumn.ValueMember = ""; // Once again, I don't know what to set this to
I also presume I should have a line that sets the DataSource for the column, e.g.
tagsColumn.DataSource = <some LINQ query, perhaps?>
but I don't know because the only mostly relevant C# source I've been able to find is that question.
UPDATE:
I did find a second question that suggests code similar to this for data binding:
// reference the combobox column
DataGridViewComboBoxColumn cboBoxColumn = (DataGridViewComboBoxColumn)dataGridView1.Columns[0];
cboBoxColumn.DataSource = Choice.GetChoices();
cboBoxColumn.DisplayMember = "Name"; // the Name property in Choice class
cboBoxColumn.ValueMember = "Value"; // ditto for the Value property
Based on that, I a) added the GetTags() method to SearchResult and added this code into my DataGridView initialisation code:
DataGridViewComboBoxColumn tagsColumn = new DataGridViewComboBoxColumn();
tagsColumn.DataSource = SearchResult.GetTags(); // ERROR
tagsColumn.DisplayMember = ""; // Still not sure
tagsColumn.ValueMember = ""; // ??
However, Visual Studio gives me an error on the second line when I try to run this:
An object reference is required for the non-static field, method, or property 'SearchResult.GetTags()'
UPDATE 2:
I'm still searching around for this without success. I don't understand how with other properties (e.g. EventId) I can simply declare the data property name as EventId, and it will display in the table, but I cannot do this with ComboBox columns.
Since the objects are instantiated in a separate class and put in a list, it doesn't seem to make sense to me that I should have to loop through the entire array of objects (of which there may be several hundred) to bind the Tags property to the ComboBox column for each instance, when I don't need to loop through the list of SearchResult objects to bind other properties, e.g. EventId.
Why does this binding-properties-by-name only work for some properties and not others?
I don't quite understand why you want to use DataGridViewComboBoxColumn to display a list of elements. This column kind is designed to allow user to select one of many possibilities. It seams it is not your case because you don't have public string SelectedTag{get;set;} property to store it. As I understand your model you have many tags already selected for your SearchResult and you want to display them in grid.
As documentation states:
http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridviewcomboboxcolumn.datasource
Getting or setting this [DataSource] property gets or sets the DataSource property of the object returned by the CellTemplate property. Setting this property also sets the DataSource property of every cell in the column and refreshes the column display. To override the specified value for individual cells, set the cell values after you set the column value.
DataGridViewComboBoxColumn simply does not have capability to bind items property to data source because it assumes that there is only one list of elements that is used as data source for all rows of data grid.
I also assume that you would set ReadOnly = true property for this column as you have for all other. If so it would prevent user form seeing list of tags because drop down list would never be displayed.
If you wand to display list of strings in read only mode I would suggest to flatten this list of tags to single string:
public string Tags { get { return string.Join(", ", tags); } }
and display it in text column.
For the error , i can suggest you to make an instance of the class and then call the method as its not static or you can make your method static.
Moreover As you needs the comboboxcolumn ,
DataGridViewComboBoxColumn tagsColumn = new DataGridViewComboBoxColumn();
tagsColumn.DataSource = SearchResult.GetTags(); // ERROR
tagsColumn.DisplayMember = ""; // Still not sure
tagsColumn.ValueMember = ""; // ??
Mostly we have dropdowns for objects like Country(id,name) so DisplayMember = name will be shown as text in dropdown while ValueMember = id will be used in the referencing tables in database.But this is not your case.
Here you have a list of strings to show in dropdown , so you don't need to set them.
As written here
If the DataSource property is set to a string array, then ValueMember
and DisplayMember do not need to be set because each string in the
array will be used for both value and display.

set combobox text from textbox

I have user submitted content that is loaded into c# winform in our office for processing before officially added to database. The user can submit a 'Referrer' as two text fields-first and last name. In the office I want to have a combobox will all existing referrers loaded in, then the first couple letters of the name to advance the combobox down to the area it needs to be at. I want to do something like this, taking the first two letters of the name and use that to initialize the combobox.
if (txtrefFirstName.TextLength > 2)
{
string firstStart = "" + txtrefFirstName.Text[0] + txtrefFirstName.Text[1];
firstStart = firstStart.ToUpper();
ddlReferring.SelectedText.StartsWith(firstStart);
}
else
ddlReferring.Text = "";
Any ideas or suggestions to get this to work?
Thanks
David K.
You could write something like this...
foreach (string item in ddlReferring.Items)
{
if (item.StartsWith(firstStart))
{
ddlReferring.SelectedText = item;
break;
}
}
Assuming the ddl's datasource is a List of String objects, you should be able to do some comparison on the datasource itself. I tend to use Linq for things like this but it isn't strictly necessary, just shorter.
if (txtrefFirstName.TextLength > 2)
{
string firstStart = txtrefFirstName.Text.Substring(0,2).ToUpper();
string Selection = ddlReferring.DataSource.Where(a=>a.StartsWith(firstStart)).FirstOrDefault();
ddlReferring.SelectedText = Selection ?? "";
}
else
ddlReferring.Text = "";
The selection line can also come from the items collection directly
string Selection = ddlReferring.Items.OfType<string>().Where(a=>a.StartsWith(firstStart)).FirstOrDefault();
Or if you REALLY dont want to use Linq...
string Selection = "";
foreach (object item in ddlReferring.Items)
if (item.ToString().StartsWith(firstStart))
{
Selection = item.ToString();
break;
}
Similar methods can be used even if the ddl's data is not a list of strings, just make sure to cast the items appropriately and compare the correct values.

C#: Custom sort of DataGridView

I need to sort a DataGridView with Natural Sorting (Like in Explorer) so that numbers and text (in the same column) are sorted naturally, and not alphabetically (so that "place 3" comes before "place 20", etc.). I have a DataGridView, where I have set a DataView as DataSource. The DataView contains a DataTable which is created with some values from a database. The column types are string. I have an IComparer, which does what it should, but I can't figure out how to use it, cause I can't find out how to do the sorting. The DataGridView.SortCompare event, which would be perfect, doesn't work since it is databound. The DataView.Sort, only accept strings with column names and sort orders.
Very annoying. Tried to read related issues here on StackOverflow, and searched google lots and lots, but I can't really find much about this. Only stuff I really find is using that Sort(string) method of the dataview, which wont work, since it sorts alphabetically.
Does anyone know how to do this without too much trouble? It got to be others than me struggeling with this? I really don't want to re-implement the whole datagridview or dataview classes, just to get custom sorting...
Update: In case someone were wondering, I'm still looking for a good answer to this problem. Although in the mean time, I ended up creating my own simple table class, and then feed that into a datagridview manually. Overriding the SortCompare method. Bit annoying, but wasn't too hard, since I only need to show values (no editing or anything) and therefore could convert everything to strings.
Take a look at this MSDN page and this blog post. In principle, you need to configure the sorting at the data source (whether its an ObjectDataSource or a SqlDataSource) not at the GridView.
As far as I can tell the DataView class doesn't support anything other than a simple ascending/decending sort. Without seeing the code where you load and bind the data it's hard to make a specific recommendation, but you could either:
Load your data into a List instead of a DataTable, call the Sort method passing in your comparison method and then bind to that list.
Create an ObjectDataSource in your aspx code that gets the data directly from a class, and configure that ObjectDataSource to use your IComparer.
This code should work. It is similar to ListView's ListViewItemSorter. Using IComparer.
To use:
private void dgv_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
MyDataGridHelper.DataGridSort(dgv, e.ColumnIndex);
}
MyDataGridHelper.cs:
public class MyDataGridHelper
{
public static void DataGridSort(DataGridView dgv, int column)
{
DataGridViewCustomSorter dgvSorter = null;
if (dgv.Tag == null || !(dgv.Tag is IComparer))
{
dgvSorter = new DataGridViewCustomSorter(dgv);
dgv.Tag = dgvSorter;
}
else
{
dgvSorter = (DataGridViewCustomSorter)dgv.Tag;
}
dgvSorter.SortColumn = column;
dgv.Sort(dgvSorter);
}
private class DataGridViewCustomSorter : IComparer
{
private int ColumnIndex;
private SortOrder OrderOfSort;
private DataGridView myDataGridView;
private TypeCode mySortTypeCode;
public DataGridViewCustomSorter(DataGridView dgv)
{
myDataGridView = dgv;
mySortTypeCode = Type.GetTypeCode(Type.GetType("System.String"));
ColumnIndex = 0;
OrderOfSort = SortOrder.None;
}
public int Compare(object x, object y)
{
int result;
DataGridViewRow dgvX, dgvY;
dgvX = (DataGridViewRow)x;
dgvY = (DataGridViewRow)y;
string sx = dgvX.Cells[ColumnIndex].Value.ToString();
string sy = dgvY.Cells[ColumnIndex].Value.ToString();
//null handling
if (sx == String.Empty && sy == String.Empty)
result = 0;
else if (sx == String.Empty && sy != String.Empty)
result = -1;
else if (sx != String.Empty && sy == String.Empty)
result = 1;
else
{
switch (mySortTypeCode)
{
case TypeCode.Decimal:
Decimal nx = Convert.ToDecimal(sx);
Decimal ny = Convert.ToDecimal(sy);
result = nx.CompareTo(ny);
break;
case TypeCode.DateTime:
DateTime dx = Convert.ToDateTime(sx);
DateTime dy = Convert.ToDateTime(sy);
result = dx.CompareTo(dy);
break;
case TypeCode.String:
result = (new CaseInsensitiveComparer()).Compare(sx, sy);
break;
default:
result = (new CaseInsensitiveComparer()).Compare(sx, sy);
break;
}
}
if (OrderOfSort == SortOrder.Descending)
result = (-result);
return result;
}
public int SortColumn
{
set
{
if (ColumnIndex == value)
{
OrderOfSort = (OrderOfSort == SortOrder.Descending ? SortOrder.Ascending : SortOrder.Descending);
}
ColumnIndex = value;
try
{
mySortTypeCode = Type.GetTypeCode(Type.GetType((myDataGridView.Columns[ColumnIndex]).Tag.ToString()));
}
catch
{
mySortTypeCode = TypeCode.String;
}
}
get { return ColumnIndex; }
}
public SortOrder Order
{
set { OrderOfSort = value; }
get { return OrderOfSort; }
}
} //end class DataGridViewCustomSorter
} //end class MyDataGridHelper
Here there is some solution "Custom Sorting Using the SortCompare Event
" and "Custom Sorting Using the IComparer Interface":
http://msdn.microsoft.com/en-us/library/ms171608.aspx
You can create 2 hidden columns. Assign the text part to the 1st hidden column and the number part to the 2nd hidden column. Now sort by these hidden columns (alpha sort for 1st column & numeric sort for the 2nd column).
In this way, you can retain the original column for display purposes & have the 2 hidden columns for sorting.
You could move the sort logic into your database query and have it return an additional column which had the correct sort order.
Then (along the lines of #True C Sharp's answer) you could have a hidden column containing this value and sort by this rather than by the display column.
This assumes that the logic for determining the sort order can be performed in SQL. This may not work if the algorithm for determining the sort order is complex.

Categories

Resources