how can I pass value from selected field (LINQ) to textbox in winforms?
If single fields, I just do like this
var result = from row in dtValueBranch.AsEnumerable()
where row.Field<int>("branchID") == idBranch
select row.Field<string>("branchName");
StringBuilder sb = new StringBuilder();
foreach (string s in result)
{
sb.Append(s + Environment.NewLine);
}
tbBranch.Text = sb.ToString();
So this is the code LINQ to many fields
var result = from row in dtValueBranch.AsEnumerable()
where row.Field<int>("branchID") == idBranch
select new
{
BranchName = row["branchName"].ToString(),
branchTel = row["branchTel1"].ToString(),
// And many more fields
};
How can I to implement each fields to each textbox?
Keeping in mind that your result query may have multiple rows, your question appears to be focused on how to access the fields of one row. You can do that like this:
var row = result.First(); // select first row of results
textbox1.Value = row.BranchName;
textbox2.Value = row.branchTel;
// etc..
The select new syntax in your query creates an anonymous type in the result enumeration. You can't refer to that type by name, but you can create local variables (like row) if you use the var declaration style and let the compiler do type inferencing.
If you want to cram all the values of one field across all rows into into one textbox (as in your first code sample), you can do something like this:
StringBuilder sbBranch = new StringBuilder();
StringBuilder sbBranchTel = new StringBuilder();
// etc
foreach (var row in result)
{
sbBranch.Append(row.BranchName);
sbBranch.Append(Environment.NewLine);
sbBranchTel.Append(row.branchTel);
sbBranchTel.Append(Environment.NewLine);
// etc
}
tbBranch.Text = sbBranch.ToString();
tbBranchTel.Text = sbBranchTel.ToString();
// etc
However, if you're wanting to display multiple rows of multiple fields of data, you might want to look at using a data grid control instead of a herd of textboxes. You'll save yourself a lot of effort, and your users will probably thank you too.
You can do like this:
var rows = dtValueBranch.AsEnumerable()
.Where(row => row.Field<int>("branchID") == idBranch);
textBox1.Value = string.Join(Environment.NewLine,
rows.Select(row => row.Field<string>("branchName"));
textBox2.Value = string.Join(Environment.NewLine,
rows.Select(row => row.Field<string>("branchTel1"));
Related
I am trying to parse the contents of an HTML table with the following code. My issue appears when I try to update the element in the rowVals collection: it tells me that the value is read-only.
Some rows span multiple columns so I want to make sure I map the cell values to the appropriate column when I parse the table.
I know when collections are being iterated thru, it chokes when you try to update that collection. Since I am not iterating thru the rowVals collection, but rather another collection, I do not understand why my code is choking when I try to to set the value of a specific KVP element in rowVals. Can anyone suggest a way to accomplish setting the appropriate value without having to add/remove existing KVPs?
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.Load(filePath);
var root = doc.DocumentNode.Descendants().First(t => t.Name == "body");
var tables = root.Descendants().Where(t => t.Name == "table");
var trs = tables.First().Elements("tr");
//parse the headers
var headers = trs.First().Elements("th").Select(t => t.InnerText);
//parse the column values
var cells = trs.Skip(1).Select(tr => tr.Elements("td"));
//update the column values for each row
foreach (var item in cells)
{
int x = 0;
var rowVals = headers.ToDictionary(t => t, t=>"");
foreach (var item2 in item)
{
rowVals.ElementAt(x).Value = item2.InnerText;
if (item2.Attributes.Any(t => t.Name == "colspan"))
{
x = x + int.Parse(item2.Attributes.First(t => t.Name == "colspan").Value) - 1;
}
else
{
x++;
}
}
}
You can never set the value of a KeyValuePair because the property is read only to begin with. This problem has nothing to do with collection iteration.
Second, dictionaries make no guarantee about the order of the items, so using .ElementAt() makes no sense anyways.
I have a pre-populated text box with with an AutoCompleteCustomSource:
var source = new AutoCompleteStringCollection();
using(propertiesManagementDataContext db = new propertiesManagementDataContext())
{
var q =
(from t in db.GetTable<Tenant>()
select t.lname + " " + t.fname).ToArray();
source.AddRange(q);
}
txt_callerName.AutoCompleteCustomSource = source;
txt_callerName.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
txt_callerName.AutoCompleteSource = AutoCompleteSource.CustomSource;
It works fine, but I want to know the ID of the auto completed item. How to get it?
I tried like this, but had an error:
var q =
(from t in db.GetTable<Tenant>()
select new {lfname = t.lname + " " + t.fname, t.tenantID}).ToArray();
source.AddRange(q);
//this does not work, because q is not an array of strings anymore
How to autocomplete the textbox and save the connection between Lname, Fname and tenantID of the autocompleted items?
I don't see anything in the AutoCompleteStringCollection class that allows you store extra data for each string ... it's pretty much just a collection of strings.
This isn't ideal, but you could include the ID at the end of the string so it doesn't affect the auto-complete experience while the user is typing, then parse the value back out when they make a selection:
var q =
(from t in db.GetTable<Tenant>()
select string.Format("{0} {1} ({2})", t.lname, t.fname, t.tenantID)).ToArray();
Alternatively, you could use a ComboBox control, which (when configured properly) does everything your TextBox is doing, as well as supports setting the data source to a collection of any class you want (not limited to a collection of strings).
You would then specify the property visible to the user (name) with DisplayMember and then the value of each item (ID) with ValueMember.
You could store all the additional data in parallel Dictionary (or other similar collection)
var q =
(from t in db.GetTable<Tenant>()
select new {lfname = t.lname + " " + t.fname, t.tenantID});
Dictionary<String, Int32> idDictionary = new Dictionary<String, Int32>();
foreach(var item in q)
{
idDictionary.Add(item.lfname, item.tenantID);
source.AddRange(q);
}
...
String currentSuggestion = ...
Int32 id = idDictionary[currentSuggestion];
dbContext.Entities.RemoveById(id);
That is not the ideal solution, because you will have to somehow associate for each textBox with AutoCompletion its own dictionary(either storing it in parallel, or subclassing the TextBox). Also there is possibility that lfname can occur twice in the query.
I'm working on an importer that takes tab delimited text files. The first line of each file contains 'columns' like ItemCode, Language, ImportMode etc and there can be varying numbers of columns.
I'm able to get the names of each column, whether there's one or 10 and so on. I use a method to achieve this that returns List<string>:
private List<string> GetColumnNames(string saveLocation, int numColumns)
{
var data = (File.ReadAllLines(saveLocation));
var columnNames = new List<string>();
for (int i = 0; i < numColumns; i++)
{
var cols = from lines in data
.Take(1)
.Where(l => !string.IsNullOrEmpty(l))
.Select(l => l.Split(delimiter.ToCharArray(), StringSplitOptions.None))
.Select(value => string.Join(" ", value))
let split = lines.Split(' ')
select new
{
Temp = split[i].Trim()
};
foreach (var x in cols)
{
columnNames.Add(x.Temp);
}
}
return columnNames;
}
If I always knew what columns to be expecting, I could just create a new object, but since I don't, I'm wondering is there a way I can dynamically create an object with properties that correspond to whatever GetColumnNames() returns?
Any suggestions?
For what it's worth, here's how I used DataTables to achieve what I wanted.
// saveLocation is file location
// numColumns comes from another method that gets number of columns in file
var columnNames = GetColumnNames(saveLocation, numColumns);
var table = new DataTable();
foreach (var header in columnNames)
{
table.Columns.Add(header);
}
// itemAttributeData is the file split into lines
foreach (var row in itemAttributeData)
{
table.Rows.Add(row);
}
Although there was a bit more work involved to be able to manipulate the data in the way I wanted, Karthik's suggestion got me on the right track.
You could create a dictionary of strings where the first string references the "properties" name and the second string its characteristic.
I am trying o set textboxes on an ASP.NET webpage using LINQ - SQL. Here is the code I have to perform the select statement:
EQCN = Request.QueryString["EQCN"];
var equipment = from n in db.equipments
where n.EQCN.ToString() == EQCN
select n;
How do I set TextBox1.text to be a specific field in the table?
Thanks so much
EDIT
I need to output every field in the table into different textboxes. So performing a query for ever single one seems a little much. There has to be a way to do this?
Thanks
Well you can select the appropriate field to start with:
EQCN = Request.QueryString["EQCN"];
var values = from n in db.equipments
where n.EQCN.ToString() == EQCN
select n.FieldYouWant;
// Or possibly Single, or First...
var singleValue = values.FirstOrDefault();
I think that's what you were after, but if it's not, please clarify your question.
EDIT: To answer your follow-up, you can use:
EQCN = Request.QueryString["EQCN"];
var query = from n in db.equipments
where n.EQCN.ToString() == EQCN
select n;
// Or possibly Single, or First...
var entity = query.Single();
textBox1.Text = entity.Name;
textBox2.Text = entity.Description;
textBox3.Text = entity.Title;
// etc
That's assuming you want to have access to everything in the entity. If the entity is very large and you only need a few fields, you might want to do something like this:
EQCN = Request.QueryString["EQCN"];
var query = from n in db.equipments
where n.EQCN.ToString() == EQCN
select new { n.Name, n.Description, n.Title };
// Or possibly Single, or First...
var projection = query.Single();
textBox1.Text = projection.Name;
textBox2.Text = projection.Description;
textBox3.Text = projection.Title;
I'm not sure I'd actually couple the data access and UI layers so closely, but that's a different matter...
You only need to perform the query once, but once that's done, you'll have to assign each field to a TextBox. Start by retrieving only the single item you want:
EQCN = Request.QueryString["EQCN"];
var equipment = (from n in db.equipments
where n.EQCN.ToString() == EQCN
select n).FirstOrDefault();
Then go through and assign each TextBox to the appropriate field:
txtName.Text = equipment.Name;
txtDescription.Text = equipment.Description;
txtValue1.Text = equipment.Value1;
txtValue2.Text = equipment.Value2;
//...
If you have several dozen TextBoxes to assign, you could set up a custom control that can be databound to an equipment object, but even then, you'll still have to write the binding code for your control.
The only way I can think of to totally automate this process is to name each TextBox after a field in your object, then use reflection to match them to values:
var textboxes = Panel1.Controls.OfType<TextBox>();
foreach (TextBox txt in textboxes)
{
string fieldname = txt.ID.Remove(0, 3); //"txtDescription" becomes "Description"
string value = equipment.GetType().GetProperty(fieldname).GetValue(equipment, null) as string;
txt.Text = value;
}
I have a requirement to extract a distinct subset of rows from a DataTable, and thought LINQ2DataSets may be a useful and clean way to do this, however it appears that it is not possible to simply identify return rows from a LINQ2DS query as follows
var result = from r in fips.AsEnumerable() select
r.Field<string>("FACILITY_PROCESS_SUB_GROUP_CODE"),
r.Field<string>("PROCESS_SUB_GROUP_NAME"),
r.Field<string>("...
as I start getting errors after the first comma.
Is this a correct assumption, and how would I get around it to return a subset of columns from the dataset that I can apply a Distinct() method to?
You forgot the new statement and field names:
var result = from r
in fips.AsEnumerable()
select new
{
FacProcess = r.Field<string>("FACILITY_PROCESS_SUB_GROUP_CODE"),
GroupName = r.Field<string>("PROCESS_SUB_GROUP_NAME"),
Item3 = r.Field<string>("Item3")
};
You can also explicitly declare that you are going to use a type:
var result = from r
in fips.AsEnumerable()
select new MyType("InitClassParams")
{
FacProcess = r.Field<string>("FACILITY_PROCESS_SUB_GROUP_CODE"),
GroupName = r.Field<string>("PROCESS_SUB_GROUP_NAME"),
Item3 = r.Field<string>("Item3")
};
Scott Guthrie (VP Developer Devision, Microsoft) has some good info about LINQ (he talks about LINQ to SQL, but most of it applies regardless).
Then apply the distinct clause:
var result = from r
in fips.AsEnumerable()
select new
{
FacProcess = r.Field<string>("FACILITY_PROCESS_SUB_GROUP_CODE"),
GroupName = r.Field<string>("PROCESS_SUB_GROUP_NAME"),
Item3 = r.Field<string>("Item3")
}
distinct;
Then put it to a list or iterate over it. Nothing will be selected/distincted/etc until something like on of the following is run:
var list = result.ToList()
foreach(var item in result) {}