In a dropdown I've got a list of country of this type:
Text: "Italy" Value :"IT"
I need a copy of one of the country in the top of the list referred to the current language of the portal I'm working in, so the user can both select the first or the one into the list. Is just a hint we can say.
So I've just added a copy in this way:
cmbNazione.Items.Insert(0, cmbNazione.Items.FindByText(valori.Rows[0]["M_SOAAuthorityCountry"].ToString().ToUpper()));}
This code works fine. I got my duplicate value and I can select it without problem.
I am stuck when I already have a country that I have to set into the dropDown.
I just wrote that:
cmbNazione.Items.Insert(0, cmbNazione.Items.FindByText(valori.Rows[0]["M_SOAAuthorityCountry"].ToString().ToUpper()));
cmbNazione.ClearSelection();
cmbNazione.Items.FindByText(valori.Rows[0]["M_SOAAuthorityCountry"].ToString().ToUpper()).Selected = true;
The problem is that I receive the error: Cannot have multiple items selected in a DropDownList.
In fact if I check I got both the list Items (first, and the identical in the list) with the prop : selected = true. If I try to make one false both change to false. I cannot use them separately.
I can't understand why I can use them correctly when I select manually, as a user, but not when I try to select them through code.
I also tried something like :
cmbNazione.SelectedIndex = cmbNazione.Items.IndexOf(cmbNazione.Items.FindByText(valori.Rows[0]["M_SOAAuthorityCountry"].ToString().ToUpper()));
But nothing. I'll every time have multiple items in the list of the selected
You should not have a duplicate value as it will confuse the user (if the value is on 2-3 position already) and architecture as retrieval may lead to 2 values being selected.
Your use case seem like you are offering the most commonly used value as the first one and then the remaining. If this is the case, follow the approach outlined below.
Find the ListItem required, then remove it from the list and add on the 1st position. Then mark it as selected.
var preferredItem = cmbNazione.Items.FindByText(...);
if (preferredItem != null) {
cmbNazione.Items.Remove(preferredItem);
cmbNazione.Items.Insert(0, preferredItem);
cmbNazione.SelectedItemIndex = 0;
}
This way, there will be single item being selected and preserve the sanctity of the item (underlying value etc) while still allowing user to have the preferred one on top of list. You can chose to have this as 'pre-selected' or let user select it explictly.
Related
I have a situation wherein a List object is built off of values pulled from a MSSQL database. However, this particular table is mysteriously getting an errant record or two tossed in. Removing the records cause trouble even though they have no referential links to any other tables, and will still get recreated without any known user actions taken. This causes some trouble as it puts unwanted values on display that add a little bit of confusion. The specific issue is that this is a platform that allows users to run a search for quotes, and the filtering allows for sales rep selection. The select/dropdown field is showing these errant values, and they need to be removed.
Given that deleting the offending table rows does not provide a desirable result, I was thinking that maybe the best course of action was to modify the code where the List object is created and either filter the values out or remove them after the object is populated. I'd like to do this in a clean, scalible fashion by providing some kind of appendable data object where I could just add in a new string value if something else cropped up as opposed to doing something clunky that adds new code to find the value and remove it each time.
My thought was to create a string array, and somehow loop through that to remove bad List values, but I wasn't entirely certain that was the best way to approach this, and I could not for the life of me think of a clean approach for this. I would think that the best way would be to add a filter within the Find arguments, but I don't know how to add in an array or list that way. Otherwise I figured to loop through the values either before or after the sorting of the List and remove any matches that way, but I wasn't sure that was the best choice of actions.
I have attached the current code, and would appreciate any suggestions.
int licenseeID = Helper.GetLicenseeIdByLicenseeShortName(Membership.ApplicationName);
List<User> listUsers;
if (Roles.IsUserInRole("Admin"))
{
//get all users
listUsers = User.Find(x => x.LicenseeID == licenseeID).ToList();
}
else
{
//get only the current user
listUsers = User.Find(x => (x.LicenseeID == licenseeID && x.EmailAddress == Membership.GetUser().Email)).ToList();
}
listUsers.Sort((x, y) => string.Compare(x.FirstName, y.FirstName));
-- EDIT --
I neglected to mention that I did not develop this, I merely inherited its maintenance after the original developer(s) disappeared, and my coworker who was assigned to it left the company. I'm not really really skilled at handling ASP.NET sites. Many object sources are hidden and unavailable for edit, I assume due to them being defined in a DLL somewhere. So, for any of these objects that are sourced from database tables, altering the tables will not help, since I would not be able to get the new data anyway.
However, I did try to do the following to filter out the undersirable data:
List<String> exclude = new List<String>(new String[] { "value1" , "value2" });
listUsers = User.Find(x => x.LicenseeID == licenseeID && !exclude.Contains(x.FirstName)).ToList();
Unfortunately it only resulted in an error being displayed to the page.
-- EDIT #2 --
I got the server setup to accept a new event viewer source so I could write info to the Application log to see what was happening. Looks like this installation of ASP.NET does not accept "Contains" as an action on a List object. An error gets kicked out stating that the method is not available.
I will probably add a bit to the table and flag Errant rows and then skip them when I query the table, something like
&& !ErrantData
Other way, that requires a bit more upkeep but doesn't require db change, would be to keep a text file that gets periodically updated and you read it and remove users from list based on it.
The bigger issue is unknown rows creeping in your database. Changing user credentials and adding creation timestamps may help you narrow down the search scope.
I m having a little trouble coming up with a schema to order and changing order in a article/news management system.
Here goes:
I have News Object Model as follow:
class News {
int id;
string Title;
string Content;
string OrderId;
// trimmed
}
I have CRUD for the object model. and List as follows:
Id Title Order
1. Foo -+
2. Bar -+
3. Glah -+
What i want to do is when user clicks on - for first news, i want to replace 1 and 2 orderid and of course display as well.
well how do i do this on server side? lets say for 1. item order id is 1 , how do i find the first item that has a higher order id then this one?
Or take 2. Bar, when i click on - , how do i find/replace order ids with first one. or i click on + how do i replace order id of this news with 3. Glah ?
is there a better way of doing this?
There are also some UI where user drags and drops ? any pointers on that?
When the user changes the location of an item, the server needs to know which item was changed and what it's new position is. In the code below, I'm using a List to figure out the new positons. In this sample code, newPosition is the new zero-based position and selectedArticle is the article that was moved.
List<Article> articles = LoadSortedArticles()
articles.Remove(selectedArticle);
articles.Insert(newPosition, selectedArticle);
UpdateArticles(articles);
After running, the article's index within the list tells you its new position. That applies to all articles in the list and works the same for a drag/drop UI. I don't know entity framework, but if you can map the orderId field in the database to the index of the article in the list, then you should be good to go.
I hope this is at least able to give you some ideas. Maybe someone else can give a solution specific to entity framework, but I think putting the articles into a sorted list and letting the list do the work might be the easiest way.
I think the best approach here would be to implement a Swap method that takes two News objects and swaps their OrderId, which I am assuming is numeric.
So the idea would be that you would pass this method the object that was clicked on, as well as either the one above (if the user clicked +) or the one below (if they clicked -). If you do it this way then you avoid the task of trying to find the next or previous item.
In the case of drag and drop, the task is a little different. You would first need to retrieve all the items between (and including) the item being dragged and the drop target, ordered by OrderId. From there you swap the dragged item with the next or previous item (depending on direction), and continue doing so until you have swapped it with the drop target.
Let's say we have a code list of all the countries including their country codes. The country code is primary key of the Countries table and it is used as a foreign key in many places in the database. In my application the countries are usually displayed as dropdowns on multiple forms.
Some of the countries, that used to exists in the past, don't exist any more, for example Serbia and Montenegro, which had the country code of SCG.
I have two objectives:
don't allow the user to use these old values (so these values should not be visible in dropdowns when inserting data)
the user should still be able to (readonly) open old stuff and in this case the deprecated values should be visible in dropdowns.
I see two options:
Rename deprecated values, for instance from 'CountryName' to '!!!!!CountryName'. This approach is the easiest to implement, but with obvious drawbacks.
Add IsActive column to Countries table and set it to false for all deprecated values and true for all other. On all the forms where the user can insert data, display only values which are active. On the readonly forms we can display all values (including deprecated ones) so the user will be able to display old data. But on some of my forms the user should be able to also edit data, which means that the deprecated values should be hidden from him. That means, that each dropbox should have some initialization logic like this: if the data displayed is readonly, then include deprecated values in dropbox and if the data is for edit also, then exclude them. But this is a lot of work and error prone too.
And other ideas?
I deal with this scenario a lot, and use the 'Active' flag to solve the problem, much as you described. When I populate a drop-down list with values, I only load 'active' data and include upto 1 deprecated value, but only if it is being used. (i.e. if I am looking at a person record, and that person has a deprecated country, then that country would be included in the Drop-downlist along with the active countries. I do this in read-only AND in edit modes, because in my cases, if a person record (for example) has a deprecated country listed, they can continue to use it, but once they change it to a non-deprecated country, and then save it, they can never switch back (your use case may vary).
So the key differences is, even in read-only mode I don't add all the deprecated countries to the DDL, just the deprecated country that applies to the record I am looking at, and even then, it is only if that record was already in use.
Here is an example of the logic I use when loading the drop down list:
protected void LoadSourceDropdownList(bool AddingNewRecord, int ExistingCode)
{
using (Entities db = new Entities())
{
if (AddingNewRecord) // when we are adding a new record, only show 'active' items in the drop-downlist.
ddlSource.DataSource = (from q in db.zLeadSources where (q.Active == true) select q);
else // for existing records, show all active items AND the current value.
ddlSource.DataSource = (from q in db.zLeadSources where ((q.Active == true) || (q.Code == ExistingCode)) select q);
ddlSource.DataValueField = "Code";
ddlSource.DataTextField = "Description";
ddlSource.DataBind();
ddlSource.Items.Insert(0, "--Select--");
ddlSource.Items[0].Value = "0";
}
}
If you are displaying the record as read-only, why bother loading the standing data at all?
Here's what I would do:
the record will contain the country code in any case, I would also propose returning the country description (which admittedly makes things less efficient), but when the user loads "old stuff", the business service recognises that this record will be read only, and you don't bother loading the country list (which would make things more efficient).
in my presentation service I will then generally do a check to see whether the list of countries is null. If not (r/w) load the data into the list box, if so (r/o) populate the list box from the data in the record - a single entry in the list equals read-only.
You can filter with CollectionViewSource or you could just create a Public Enumerable that filters the full list using LINQ.
CollectionViewSource Class
LINQ The FieldDef.DispSearch is the active condition. IEnumerable is a little better performance than List.
public IEnumerable<FieldDefApplied> FieldDefsAppliedSearch
{
get
{
return fieldDefsApplied.Where(df => df.FieldDef.DispSearch).OrderBy(df => df.FieldDef.DispName);
}
}
Why would you still want to display (for instance) customer-addresses with their OLD country-code?
If I understand correctly, you currently still have 'address'-records that still point to 'Serbia and Montenegro'. I think if you solve that problem, your current question would be none-existent.
The term "country" is perhaps a little misleading: not all the "countries" in ISO 3166 are actually independent. Rather, many of them are geographically separate territories that are legally portions or dependencies of other countries.
Also note that 'withdrawn country-codes' are reserved for 5 years, meaning that after 5 years they may be reused. So moving away from using the country-code itself as primary key would make sense to me, especially if for historical reasons you would need to back-track previous country-codes.
So why not make the 'withdrawn' field/table that points to the new country-id's. You can still check (in sql for instance, since you were already using a table) if this field is empty or not to get a true/false check if you need it.
The way I see it: "Country" codes may change, country's may merge and country's may divide.
If country's change or merge, you can update your address-records with a simple query.
If country's divide, you need a way to determine what address is part of what country.
You could use some automated system do do this (and write lengthly books about it).
OR
(when it is a forum like site), you could ask the users that still have a withdrawn country that points to multiple alternatives in their account to update their country-entry at login, where they can only choose from the list of new country's that are specified in the withdrawn field.
Think of this simplified country-table setup:
id cc cn withdrawn
1 DE Germany
2 CS Serbia and Montenegro 6,7
3 RH Southern Rhodesia 5
4 NL The Netherlands
5 ZW Zimbabwe
6 RS Serbia
7 ME Montenegro
In this example, address-records with country-id 3, get updated with a query to country-id 5, no user interaction (or other solution) needed.
But address-records that specify country-id 2 will be asked to select country-id 6 or 7 (of course in the text presented to the user you use the country-name) or are selected to perform your custom automated update routine on.
Also note: 'withdrawn' is a repeating group and as such you could/should make it into a separate table.
Implementing this idea (without downtime) in your scenario:
sql statement to build a new country-table with numerical id's as primary key.
sql statement to update address-records with new field 'country-id' and fill this field with the country-id from the new country-table that corresponds with country-code specified in that record's address-field.
(sql statement to) create the withdrawn table and populate the correct data with in it.
then rewrite your the sql statements that supply your forms with data
add the check and 'ask user to update country'-routine
let new forms go live
wait/see for unintended bugs
delete old country-table and (now unused) country-code column from the "address"-table
I am very curious what other experts think about this idea!!
I have a gridview, bound to a datasource whose database table contains a foreign key that is associated with the database table that is used as the datasource for a dropdownlist.
What I want to do is if a certain foreignKeyId exists in gridview.datasource, to remove it from dropdownlist.datasource.
To give a clearer idea of what/why I want what I want, the user is able to add entries to the gridview (and therefore the datasource), but I don't want the user to be able to make more than one entry for a specific type. Is there a way that a linq query could do this?
pseudocode (note that I know RemoveObjects() is an invalid method)
var query = DataContext.Items.Where(item => item.TypeId == selectedTypeId);
dropDownList.DataSource.RemoveObjects(query);
Here is how I bind the dropdownlist, so maybe I could do something here to not get the items with already existing TypeId's?
dropDownList.DataSource = DataContext.Items.Select(items => new
{
items.Name,
items.TypeId,
}).ToList();
Any suggestions or answers would be great!
Have you tried using except
dropDownList.DataSource.Except(query)
I have a Windows.Forms.ListView where the user shall be able to add and remove entries. Particularly, those are files (with attributes) the user can pick through a dialog. Now, I want to check whether the file names / entries I get from the file picker are already in the list; in other words, there shall only be unique items in the ListView.
I could not find any way to compare ListViewItems to check whether the exact same entry and information is already present in my ListView. The only way I see now is to:
> Loop through the files I get from the picker (multiselect is true)
> Loop through ListView.Items
compare ListViewItem.Text
> Loop through ListViewItem.SubItems
compare .Text
If during the comparisons a complete match was found, the new entry is a duplicate and thus is not added afterwards.
This seems like an awful lot of effort to do something that I would find to be a function that is not so uncommon. Is there any other way to achieve this?
The file system itself uses only the filename to test for uniqueness, so you should do the same, no need to compare sub-items too.
Items in a ListView typically represent some object. What I usually do is to assign that object (or at least some value identifying the object) to the Tag property of the corresponding ListViewItem when they are added to the list. That way you get a quite simple setup where you can compare items by getting the values from the Tag property and perform the comparison on those objects instead of the list view representation of them.