Hello i have a datagridview which has datasource of list and this list is:
public class UniqueNounWithFreq
{
public int freq { get; set; }
public string word { get; set; }
public UniqueNounWithFreq(string word, int freq)
{
this.freq = freq;
this.word = word;
}
}
if (e.KeyChar == (char)13)
{
foreach (DataGridViewRow item in dataGridView_w2wm2.Rows)
{
if (!item.Cells[2].Value.ToString().Contains(textBox1.ToString().ToLower()))
{
item.Visible = false;
}
else
{
item.Visible = true;
}
}
}
When I want to hide a row with key press it throws
Row associated with the currency manager's position cannot be made invisible exception
Which you can see here : Unable To set row visible false of a datagridview. I tried the method sugested there but it did not work for me. Also when I check the lengths of the strings I wrote even if they are same they does not match. if you can help me I appreciate that.
Using textBox1.ToString() will generate something like "System.Windows.Controls.TextBox: TextBox" - it will create a string of the control type.
You should be using textBox1.Text to get the actual contents of the textbox - it is a string, so does not need converting.
Following on from PeterBruins comment using .Contains(textBox1.Text, StringComparer.CurrentCultureIgnoreCase) would be better than converting to lower case.
You could simplify setting the Visible property without use of an if statement to :
item.Visible = item.Cells[2].Value.ToString().Contains(textBox1.Text,
StringComparer.CurrentCultureIgnoreCase);
Related
I am reading rows from a table in SQL Server using C# in SSIS. As I loop through each column I want to get the datatype of the field from the table. Here is my code:
string s = "";
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
using (System.IO.StreamWriter file =
new System.IO.StreamWriter(#"C:\Users\cassf\Documents\Tyler Tech\FL\ncc3\CM_Property.csv", true))
{
foreach (PropertyInfo inputColumn in Row.GetType().GetProperties())
{
if (!inputColumn.Name.EndsWith("IsNull"))
{
try
{
s += Convert.ToString(inputColumn.GetValue(Row,null).ToString());
}
catch
{
some code
}
}
}
}
}
First issue is when I do the Convert.ToString() on a Bit field from the database, it changes the value to either True or False. I want the actual value of 1 or 0.
So to try and fix this I want to check the field type for Boolean, it appears that the script is converting from a bit to boolean. Then I can manually put the 1 or 0 back. I would prefer to have the value directly from the database though.
Any help would be greatly appreciated.
Thanks,
Kent
I'd implement a helper function to make your own conversion, when needed, like this:
string s = "";
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
using (System.IO.StreamWriter file =
new System.IO.StreamWriter(#"C:\Users\cassf\Documents\Tyler Tech\FL\ncc3\CM_Property.csv", true))
{
foreach (PropertyInfo inputColumn in Row.GetType().GetProperties())
{
if (!inputColumn.Name.EndsWith("IsNull"))
{
try
{
s += ValueToString(inputColumn.GetValue(Row,null));
}
catch
{
some code
}
}
}
}
}
protected string ValueToString(object value)
{
if (value == null)
throw new ArgumentNullException("I don't know how to convert null to string, implement me!");
switch (Type.GetTypeCode(value.GetType()))
{
// Any kind of special treatment, you implement here...
case TypeCode.Boolean: return Convert.ToInt16(value).ToString();
default: return value.ToString(); // ...otherwise, just use the common conversion
}
}
For booleans, you just convert it to Int, and the int to string (you'll get 1 or 0 in string format).
Depending on what you're going to do with the s variable, you might want to surround string values with quotes, if so, you could do it inside ValueToString() method.
I have a dropdownlist on a web form that has an item name and a price associated with it (which is not visible to the user). I am using selecteditem.Text and selectedvalue to capture the item name and the price. To combat duplicate entries for the selectedvalue I am storing entries like so
Signed Cap 10.0
Signed Glove 10.1
Signed Shirt 10.2
Bat Shavings .50
Hat Brim .50
Then parsing it out by using the below
String[] str = dropdownlist1.SelectedValue.ToString().Split('.');
String itemprice = str[0].Trim();
My syntax works great, EXCEPT for the decimal values! On Bat Shavings and Hat Brim I need to retain the decimal value! What should I alter or how should I set up my syntax to allow duplicate selected values or to keep the decimals? I understand that using str[0] is what is causing me to loose the decimals, BUT how can I work around it for the 2 (possibly more in the future) scenarios where they need to be remain in tact?
Its hard to tell from your posting how your getting your data, but I would load my data from the database into a data object, then bind that object to the drop down list.
Here is the Inventory Class I used to store the data from the database:
public class Inventory
{
public int ProductID { get; set; }
public string ProductDescription { get; set; }
public decimal ProductPrice { get; set; }
public Inventory(int ID, string Description, decimal Price)
{
this.ProductID = ID;
this.ProductDescription = Description;
this.ProductPrice = Price;
}
public string DDLValue
{
get
{
return string.Format("{0}|{1}|{2}", ProductID, ProductDescription, ProductPrice);
}
}
public string DDLText
{
get
{
return string.Format("{0} [{1}]", ProductDescription, ProductPrice.ToString("C"));
}
}
}
Here is a sample of how to configure the page control:
<asp:DropDownList ID="ddlProducts" runat="server" DataValueField="DDLValue" DataTextField="DDLText" />
In the page code behind, load your data into the drop down:
protected void LoadProductsFromDatabase()
{
System.Collections.Generic.List<Inventory> My_DDL_Datasource = new System.Collections.Generic.List<Inventory>();
// write your code to pull database values
// populating list with sample data for stackoverflow
// make sure to use a replace statement to remove any delimiter characters that may be in the description
My_DDL_Datasource.Add(new Inventory(1, "Product 1".Replace("|", ""), 0.50m));
My_DDL_Datasource.Add(new Inventory(2, "Product 2".Replace("|", ""), 1.50m));
My_DDL_Datasource.Add(new Inventory(3, "Product 3".Replace("|", ""), 0.50m));
My_DDL_Datasource.Add(new Inventory(4, "Product 4".Replace("|", ""), 10.50m));
ddlProducts.DataSource = My_DDL_Datasource;
ddlProducts.DataBind();
}
In the page code behind, create a method to get your drop down list selected value:
protected Inventory GetSelectedProduct()
{
try
{
if (ddlProducts.Items.Count == 0)
{
// do nothing, fall thru will return null
}
else
{
string[] DDLValue = ddlProducts.SelectedValue.Split('|');
int ivalue = 0;
int.TryParse(DDLValue.GetValue(0).ToString(), out ivalue);
decimal dvalue = 0.00m;
decimal.TryParse(DDLValue.GetValue(2).ToString(), out dvalue);
// only return object if the productid and product price were successfully parsed.
// this logic assumes no products are free
if (ivalue > 0 && dvalue > 0.00m)
{
return new Inventory(ivalue, DDLValue.GetValue(1).ToString(), dvalue);
}
}
}
catch { }
return null;
}
In the page code behind, do something with your selected value:
protected void DoSomethingWithValue()
{
Inventory MyInventoryItem = GetSelectedProduct();
if (MyInventoryItem != null)
{
// selected item successfully parsed
// do something with it.
Response.Write(
string.Format("Your selected product:<br />{0}<br />UniqueID: {1}<br />Price: {2}",
Server.HtmlEncode(MyInventoryItem.ProductDescription),
MyInventoryItem.ProductID,
MyInventoryItem.ProductPrice.ToString("C")
));
}
else
{
// error parsing information stored in drop down list value
}
}
You can split on space, and always take the last entry using linq:
dropdownlist1.SelectedValue.ToString().Split(' ').Last();
Note you should be using a hidden ItemId as the selectedvalue, instead of item name and price, and use a lookup table of:
ItemId|Name|Price
1|Hat|.50
2|Bat Shavings|.50
...
When the selected id is submitted you can lookup the name and price more directly. Also, the price being hidden in a form doesn't prevent the user from manipulating the price.
You need to remove/replace all alpha characters from string and keep only numeric.
Regex rgx = new Regex("[^a-zA-Z]");
str = rgx.Replace(str, "").Trim();
decimal prc;
Decimal.TryParse(str, out prc);
I'm trying to write an Extension methods that adds a generic Item T to the workbook, I've got problem since the UsedRange.RowCount is not incremented after InsertMethod is called
public static RowItem<T> AddItem<T>(this SpreadsheetGear.IWorksheet worksheet, T item) where T : class
{
int currentRow = worksheet.UsedRange.RowCount;
//int currentRow = worksheet.UsedRange.RowCount;
RowItem<T> newItem = new RowItem<T>
{
Item = item,
RowIndex = currentRow
};
var reflected = item.GetType().GetProperties();
for (int i = 0; i < reflected.Length; i++)
{
object value = reflected[i].GetValue(item);
worksheet.Cells[currentRow, i].Value = value;
}
worksheet.UsedRange.Insert(SpreadsheetGear.InsertShiftDirection.Down);
worksheet.WorkbookSet.CalculateFull();
return newItem;
}
public static IEnumerable<RowItem<T>> AddItems<T>(this SpreadsheetGear.IWorksheet worksheet, IEnumerable<T> items) where T : class
{
var lst = new List<RowItem<T>>();
foreach (var item in items)
{
var newItem = AddItem<T>(worksheet, item);
lst.Add(newItem);
}
return lst;
}
It's always 1 ...what am I doing wrong? my dummy class is
public class Dummy
{
public string Desciption { get; set; }
public double Value { get; set; }
public DateTime Data { get; set; }
}
And I add items as
using (var _ = new WorkbookViewLock(workbookView1))
{
var worksheet = workbookView1.ActiveSheet.Workbook.Worksheets[0];
worksheet.AddItem<Dummy>(dummy);
worksheet.AddItem<Dummy>(dummy2);
}
If you are starting out with a blank worksheet (are you?), then it would make sense that the first two checks you make to worksheet.UsedRange.RowCount in your code would have a value of 1.
This is because the UsedRange of a blank worksheet will always be A1, which would correspond to a UsedRange.RowCount value of 1. That accounts for a value of 1 for your first AddItem(...) call.
The second AddItem(...) call is now looking at a worksheet that is populated with data, but still only 1 row since you've only added a single Dummy object at this point.
If you were to add a third Dummy object, you would see that the UsedRange increments to a value of 2.
FYI: You might have an additional issue with with your worksheet.UsedRange.Insert(...) line, since this will insert the number of rows that UsedRange currently consists of. It seems to me that if you are adding just a single Dummy object with this extension method, you should only insert, at most, one row...and that depends on where you want each new Dummy row to get added to the worksheet--the top or bottom of the used range. If you are inserting the new Dummy object at the top of the UsedRange, you should only apply Insert(...) on the top row of the UsedRange. If you are inserting the new Dummy object at the bottom of the UsedRange, no Insert(...) call is necessary at all since there's nothing below the UsedRange to shift down.
In my C# window application I need wild card search on list box.
i.e If I write some text in textbox it should be auto selected in that list box.
List box is binding using datatable e.g lstVendor.datasource = l_dtTable
Findstring() function is finding match only for starting string. But I need if match find at any position in particular text then it should be highlighted.
I am Using below code but not getting index/or even lstVendor.selecteditem = "string" not working.
Indexof() always return -1
string final = "";
foreach (Object lstItem in lstVendor.Items)
{
string s = ((DataRowView)(lstItem)).Row.ItemArray[0].ToString();
if (s.ToLower().Contains(txtVendor.Text.ToLower()))
{
int i = lstVendor.Items.IndexOf(s);
final += s + ",";
}
}
string[] l_strArrVendorList = final.TrimEnd(',').Split(',');
for (int Counter = 0; Counter < l_strArrVendorList.Length; Counter++)
{
lstVendor.SelectedItem = l_strArrVendorList[Counter];
}
Searching may return multiple matched items, this code will find the first matched items:
var firstMatched = listBox1.Items.Cast<DataRowView>()
.Where(v=>Convert.ToString(v.Row[0]).ToLower()
.Contains(txtVendor.Text.ToLower()))
.FirstOrDefault();
if(firstMatched != null) listBox1.SelectedItem = firstMatched;
You can remove the FirstOrDefault() to get the list of matched items and implement some navigation through the matched items.
For VS 2000 support, you have to use this extension class:
public static class EnumerableExtension {
public static IEnumerable<T> Cast<T>(this System.Collections.IEnumerable source){
foreach(var item in source)
yield return (T)item;
}
}
My code above should work OK for you, but looks like you just want your code to be fixed instead, here is the fixed code for you:
//Note that you need to set SelectionMode for your listBox like this:
lstVendor.SelectionMode = SelectionMode.MultiSimple;
foreach (var lstItem in lstVendor.Items.Cast<DataRowView>()) {
string s = lstItem.Row.ItemArray[0].ToString();
if (s.ToLower().Contains(txtVendor.Text.ToLower())) {
lstVendor.SelectedItems.Add(lstItem);
}
}
Ok, firstly I have the following code working.. although my question is this; should I code the combobox databinding like the following example, or is there an easier/more efficient way?
Firstly, I needed to manipulate the results back from the database to show a more descriptive meaning:
(I am using a basic class for the key/value pair)
class WashBayDesc
{
public string Key { get; set; }
public string Text { get; set; }
}
Now I retrieve the data from a datareader and do the manipulation I need which then adds the results to a list item:
var washbaydata = new List<WashBayDesc>();
// Read through the available cashboxes and populate a list/combobox
while (rdr.Read())
{
string sWashBayDesc = null;
string sWB = rdr["washbay"].ToString();
if (sWB.StartsWith("3"))
{
sWashBayDesc = "Bay " + sWB.Substring(1);
}
else
{
sWashBayDesc = "Auto " + sWB.Substring(1);
}
washbaydata.Add(new WashBayDesc { Key = sWB, Text = sWashBayDesc });
}
// Now bind the hashtable (with our bay selectors) to the dropdown
cmbCashBoxes.DataSource = washbaydata;
cmbCashBoxes.ValueMember = "Key";
cmbCashBoxes.DisplayMember = "Text";
So.. the idea is I can simply bind the ComboBox datasource to the washbaydata list object.. this works fine.
The next part is to retrieve the selected item value (i.e. not the textual description, but the value or key itself). This is the bit I think maybe doesn't quite look right, although again it works...
WashBayDesc myRes = new WashBayDesc();
myRes = (WashBayDesc)cmbCashBoxes.SelectedItem;
string sWashBayCashBox = myRes.Key;
So the result is my string sWashBayCashBox has the selected key...
I guess it works, and that is fine, but is there an easier/more cleaner way?
string sWashBayCashBox = (string)cmbCashBoxes.SelectedValue;