Reputation: 127
Okay so I'm trying to create a wpf where the number of textboxes on the screen are related to the number of rows in a DataTable that match a certain criteria. I want the TextBoxes to be populated based on data from the table.
What I've tried 1)
int numContacts = 0;
List<TextBox> list = new List<TextBox>();
IEnumerable<DataRow> selectedContacts = from myRow in
ds.Tables["contacts"].AsEnumerable()
where myRow.Field<int>("company_ID") == 1
select myRow;
try
{
foreach (var item in selectedContacts)
{
list.Add(new TextBox());
// Here Is where I would like to setup the text box
// I'm not quite sure how I would do that though
numContacts++;
}
}
catch {}
Basically I want to set the properties like this:
TextBox[,] tb = new TextBox[numContacts, 3];
var width = txt_name.Width;
var height = txt_name.Height;
Thickness marginName = txt_name.Margin;
for (int i = 0; i < nametb.GetLength(0); i++)
{
tb[i, 0] = new TextBox();
tb[i, 0].HorizontalAlignment = HorizontalAlignment.Left;
tb[i, 0].VerticalAlignment = VerticalAlignment.Top;
tb[i, 0].Name = "name"+i;
tb[i, 0].Width = width;
tb[i, 0].Height = height;
tb[i, 0].Margin = new Thickness(marginName.Left, marginName.Top + (height+3)*(i+1), 0, 0);
grid.Children.Add(tb[i, 0]);
}
So is Linq the best option for this? In the future I want to create the TextBoxes then poputlate them with information from each row and then eventually save them back into the DataTable if a user makes a change.
Here is how my DataTable is setup:
DataSet ds = new DataSet();
DataTable contactTable = new DataTable("contacts");
contactTable.Columns.Add("company_ID", typeof(int));
contactTable.Columns.Add("name");
contactTable.Columns.Add("title");
contactTable.Columns.Add("email");
contactTable.Rows.Add(1, "Jim Bean", "CEO", "[email protected]");
contactTable.Rows.Add(1, "Tim Brown", "CFO", "[email protected]");
contactTable.Rows.Add(1, "Nancy Smith", "CTO", "[email protected]");
contactTable.Rows.Add(2, "Norman Jackson", "CEO", "[email protected]");
contactTable.Rows.Add(3, "Todd White", "CFO", "[email protected]");
ds.Tables.Add(contactTable);
Upvotes: 1
Views: 233
Reputation: 11064
So you're approaching this in the wrong way. A strength of WPF is its ability to decouple from your data and rely on the markup to present the data for you. This means you shouldn't be doing any presentation-layer work programmatically, but rather letting WPF do the work for you. This occurs with binding.
For example, rather than creating a presentation object in code, use WPF's markup to describe the data:
<DataGrid AutoGenerateColumns="False"
CanUserAddRows="True"
CanUserDeleteRows="True"
ItemsSource="{Binding contacts}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding company_ID}"
Visibility="Collapsed" />
<DataGridTextColumn Binding="{Binding name}" />
<DataGridTextColumn Binding="{Binding title}" />
<DataGridTextColumn Binding="{Binding email}" />
</DataGrid.Columns>
</DataGrid>
Now, by default, a DataGridTextColumn
has the IsReadonly
property set to false
. This means the cell will have the editable functionality you're looking for. Because the cell is bound, a change to its value will propagate to the data source (if the property to which it is bound is not readonly).
Hopefully that points you in the right direction. There are a few other nuances you'll encounter, but I recommend doing some research on binding to a DataGrid.
To answer your question about whether or not LINQ is the right way to approach this -- I think that may be fine if you're using LINQ in some DataAccess layer to generate the classes (or Models) to which you'll bind your DataGrid. However, I think you'll have to do some work in between LINQ and the DataGrid to handle CRUD.
Upvotes: 2