So I have 70 "nodes" which are all textboxes in WPF and I'm trying to change the value in the textbox from a function call.
I have a function called:
private void changeNode(int row, int column, int cost)
{
int nodeNumber= row * 10 + column;
call node"nodeNumber".Text = Convert.String(cost);
//example node0.Text = Convert.String(cost);
}
I determine what node I want to change then call nodeX.Text to change it however I want X to be a variable that I can rather than having to create 70 cases where I call the appropriate textbox.
I saw a couple of ways of doing this with reflection however it seemed to only work if the function had no parameters and also was within the function not a textbox in XAML.
Let me know if there is a simple way to convert say a string "node37" to call node37.Text = cost or something like that.
Sounds like your approach is wrong. Why do you have a set of strings which represent the names of the textboxes? You should instead have in-memory references to TextBox objects. If you have more than one, and you don't know how many there will be, then use an array of TextBox objects instead. You can index into the array with the number that represents the textbox you're looking to interact with.
Avoid the use of reflection, it is completely unnecessary here.
I assume you have put names for all your textboxes (you can do this dynamically if you haven't). Then you can use the answers for this question to find the appropriate control by name.
Are all your textboxes children of the same canvas or other control? Loop through the children and add the controls to a dictionary. Parse the name to get the number and use that as the key.
It is always better to use List when you are dealing with Data. Create an ObservableCollection with the DataObjects which you want to load, and now deal with the Data object rather than actual Controls.
In WPF, if you follow the rules, you should not point to the actual object. Check the sample application here :
http://www.abhisheksur.com/2010/08/woring-with-icollectionviewsource-in.html
I think you will get the approach.
Related
I have a list of Grid items called gridCache.
I have a TabItem called ti.
This line of code:
gridCache.Last().Name = ti.Name;
...is updating the Name property of every single Grid item in the list. It should just be updating the last item's Name property.
Why is it doing this?
Maybe I'm rubberducking here, but I've followed it through a break point while debugging and they all just update simultaneously when this line is called.
EDIT: I'd like to basically make 'copies' of flyGrid as it's modified to store them for later use. The idea is to use this to cache data from some SQL calls. Here's what I'm trying:
//some stuff that defines flyGrid
Grid cacheGrid = new Grid();
cacheGrid = flyGrid;
cacheGrid.Name = ti.Name;
gridCache.Add(cacheGrid);
After this recurs 3 or 4 times, the Name property of every item in the list is always the last name supplied.
How can I make a copy of flyGrid that is its own instance each time this code recurs?
SOLUTION EDIT:
I ended up solving the root problem in a completely different way. The idea was to get cached ReportParameterInfoCollection items to keep from talking to the database constantly.
I ended up creating a simple class for an object with two properties: one random string of letters, and a list of ReportParameterInfoCollection items.
This allowed me to populate this list as tabs are opened, and assign these tabs unique IDs that match the parameter information stored in this list of objects.
I didn't really solve the question, so I decided not to post this as an answer.
That would happen if every Grid is the same instance.
Make sure you're actually creating multiple instances when populating the list.
I'm in the process of creating a custom SSIS Transform. Something along the lines of the Derived column Transform that comes with SSIS. I have a list of the Input columns in a DataGridView:
The user will be able to supply a value to replace in the even that the value of the item is null.
In the past I have used CustomPropertyCollection to save single values to the ComponentMetadata. My question is. In this case where I will be storing a value for each of the input columns how should I go about that?
I have considered creating a xml string where I store the Inputcolumn id and the value I want to used to replace it with. But this seams like over kill to me. Does anyone know of a better way of going about this?
I have created, Dataflow tasks, and connection managers before. This is my first data transformation task.
I have a for each loop as follows:
foreach (PCparts parts in items)
{
MessageBox.Show(parts.PartName);
}
The loop returns 4 values in the following order: MOBO, GFX, CPU, and RAM
Now my question is, is there a way to store just one particular value into a variable or even just display it somewhere else like in a label or whatever? For example, store GFX into a variable that can be used later.
If you haven't noticed yet, I classify myself as a newbie so please don't be too harsh. I am trying to learn.
Since you have items defined as List<PCParts>, you can access the objects in the list anytime you want, so long as items is in scope.
So, for example, if you had a label (call it lblName for sake of the example), then you could do this:
lblName.Text = items[1].PartName;
Where items[1] is the second PCParts in the list (GFX).
Essentially, sine you have the list, you already have the data stored and can retrieve it. You will need to know which item your looking for, if you're looking for a specific one. For example, to build on your for each loop:
for each (PCpart part in items)
{
if (part.PartName == "GFX")
{
lblName.Text = part.PartName;
}
}
You could also use similar logic to store a selected value in a variable for further use:
string selectedPartName = items[1].PartName;
Without knowing more about what you are trying to do, it's hard to give a more definitive answer.
In the interest of giving a different, yet equally useful answer to Tim, PCParts would be more amenable to this kind of operation if it were a Dictionary rather than a List. You'd be able to access the value corresponding to the "GFX" key with an expression like items["GFX"].
I have a WinForm that have a DataGridView and a ComboBox, allowing users to select a subject (from the database).
cbxSubject.DataSource = dsSched.Tables["Schedules"];
cbxSubject.DisplayMember = "Subject";
...
The DataGridView looks something like this: http://i45.tinypic.com/18gmmu.png I added the DataGridView since I don't know any other way how to get those values from the database. I used a code, something like this, to get the values:
TextBox1.Text = DataGridView1.Rows[3].Cells[1].Value.ToString();
But then I realized that it won't work anymore if there are more than 2 subjects to choose from, because the code is set to get the value on the 3rd row and the 1st cell. So even when the user changed subject, the output value (w/c are then displayed in a TextBox) will still be the same. Are there any other ways to get those values? Please help, thanks.
You can add a comboxbox this way
DataGridViewComboBoxColumn subjectsCombo = new DataGridViewComboBoxColumn();
subjectsCombo.DataPropertyName = "SubjectID";
subjectsCombo.HeaderText = "Subjects";
subjectsCombo.DataSource = dsSched.Tables["Subjects"];
subjectsCombo.ValueMember = "SubjectID";
subjectsCombo.DisplayMember = "SubjectText";
cbxSubject.Columns.Add(subjectsCombo);
I would suggest that you DONT use constants. Rather that using 3 and 1, you need to write some code to find R and C from what the user selects. It should be event driven and you need to re-set the text box on change. I'm assuming you are using an on-change event, but you haven't actually given us that information yet.
here's some pseudocode to get where im going with this
public DataGridView1_SelectionChanged(object sender, ChangedEventArgs e)
{//this might not be the right event, I'll leave it up to you to do your own homework
int R = //Get the current Selected Row;
int C = //Get the current Selected Cell/column;
TextBox1.Text = dsSched.Tables["Schedules"].Rows[R].Cells[C];
///OR YOU COULD DO SOMETHING LIKE THIS
TextBox1.Text = ((DataGridView)sender).SelectedRows[0].Cells[1].Value;
}
//Please note, this is only pseudocode, I dont like doing peoples homework for them.
This should give you a more generic idea/algorithm that you would need. Keeping in mind that this might not even be the best way to go about doing this, but Its what I would recommend based solely on the information provided to us thus far. btw, what have you tried? and can you give us some larger code examples, there might be a rather more simple mistake being made that you haven't shown us so we cant tell you about it :-)
Considering that you still haven't actually asked the correct question, because we dont know WHY you are trying to do what you have stated you are doing, I can't get any more specific than this. GIGO, you have to ask the right question in order to get the right answer.
I'll try to get some of your doubts out of the way:
I added the DataGridView since I don't know any other way how to get
those values from the database
You already have a DataSet called "dsSched" filled with database values. So, no, you don't need the DataGridView. Just fill whatever you want directly from the DataSet:
string data = dsSched.Tables["Schedules"].Rows[3].Cells[1].Value.ToString();
then I realized that it won't work anymore if there are more than
2 subjects to choose from, because the code is set to get the value on
the 3rd row and the 1st cell.
Well, I'm not sure where you are running that piece of code (TextBox1.Text = Data...), but if you are running it on the SelectedIndexChanged event of the DataGridView, then you should get data from the exact row that the user selected (or something, again, I did not understood what you are trying to do).
One thing that I suspect is that you are under the impression that the code:
TextBox1.Text = DataGridView1.Rows[3].Cells[1].Value.ToString();
...is binding the textbox to the value in the row / cell. That's not how this works - the value is retrieved once when the code is run, and then again whenever the code is run again. So you should make sure the code is run when you have to get this value.
EDIT:
I mean, how do I get the value? Like, the PrimaryKey or something?
That's the question! I'm sorry, I was probably deviating. Just set the [ValueMember][1] to the string that describes the value column of the dataset.
cbxSubject.ValueMember = "Schedule ID";
Than you access it using [SelectedValue][2], like:
int selValue = (int)(cbxSubject.SelectedValue);
I have a situation here where the user has about 100 controls mostly multi select listboxes
but some other stuff peppered in (drop downs checkboxes) and they narrow down complex search criteria for screenings. When they go back later they want the act of pulling up a record to reset the controls to the values that they had used to match the criteria.
So I made a table that has a column for each control and iterativley stores the values - comma
deliminated for listboxes - when the user locks in the search criteria to move to the next step.
Other then using a switch to say if value is x: set control x to value(s) so and so is there a good way to iterate through this, seeing as the name of the column is the name of the control ? I'm stumped at the moment ...
var CParam = QueryFnc.RstrCntrls(Jnum, Qnum);
foreach(var a in CParam)
{
//Map Values to Matching Named Control
}
As long as your control tree remains constant, you can use control indices to map values. However better bet would be to use control IDs (if its .NET4 then go for predictable ids or manual id assignment for better controls) to map values.
Instead of storing values across columns in one row, I will prefer a table that will store values across rows. For example,
UserId ColumnName ControlID Value
------ ---------- --------- --------
1 ABC ddlAbc 52
1 XYZ ddlXyz 102, 32
...
2 XYZ ddlXyz 23
This will make things a lot simpler - get rows for the given user id and then iterate over rows. For each row, you can find the control using FindControl methods (you may have to roll up a recursive implementation in case you have naming containers in your control hierarchy) and then write simple switch statement to assign value to control based on control type.
You probably want to use reflection, and each control should have a factory method that inheits from a single interface, to allow for passing in the stored values.
With reflection you can find (and then instantiate) a control via it's name (as a string)
EDIT:
just thinking out loud here... You might also be able to use the chain of responsibility pattern, passing the name of the column along through your list of classes, and it is each objects responsibility to catch the name it is responsible for, and return an instance.