Iterate through dynamically created controls wpf - wpf

I have been searching for this but I am not able to find anything related to how to iterate through all dynamically created controls on the grid. I'm basically only looking to grab data from a dynamically created textbox, I have tried the following but it is not pulling up any children
Dim ctl As FrameworkElement = Me
Dim children As Integer = VisualTreeHelper.GetChildrenCount(ctl)
For i = 0 To children - 1
Dim Child As FrameworkElement = VisualTreeHelper.GetChild(ctl, i)
Next
Code used to add a textbox onto the form
For i = 0 To tb - 1
Dim t As New TextBox
t.Width = 75
t.Height = 25
t.Focus()
Grid.SetColumn(t, columns)
MyGrid.Children.Add(t)
t.Focus()
Next

Related

How to add button dynamically on panel which is created dynamically?

I have created a panel dynamically. How can create a button dynamically on panel which is created dynamically in WPF?
Below is my code:
Private Sub Button_Click_1(sender As Object, e As RoutedEventArgs)
Dim MyButtonUC As buttons_UC
Dim MyPanelUC As panels_UC
Dim catname As String = InputBox("Please enter category name here")
Dim MyButtonUC = New Button
MyButtonUC.Name = "btn" & catname.Replace(" ", "_").ToString
MyButtonUC.Content = catname
MyButtonUC.FontSize = 15
MyButtonUC.Height = 40
MyButtonUC.Width = 250
MyButtonUC.Margin = New Thickness(0, 3, 0, 0)
pnlCategoryButtonCont.Children.Add(MyButtonUC)
Dim MyPanelUC As New WrapPanel
MyPanelUC.Background = Brushes.Blue
MyPanelUC.Name = "pnl" & catname.Replace(" ", "_").ToString
pnlCategoryPnlContainer.Children.Add(MyPanelUC)
End Sub
In this above example I have created a button on any panel and also created a panel(A) on another panel. Now I want to add some buttons on panel(A) dynamically. Since the panel(A) is created dynamically, I could not call this directly, either i have to call this by using string, so that I can add Button on its as a children.

Is there a datagrid mouse down hit test to get the row and column index of the click?

With Winforms' DataGridView, one could use HitTest to determine the column and row index of the mouse down (and other events).
Dim hti As DataGridView.HitTestInfo = sender.HitTest(e.X, e.Y)
Is there something similar with WPF's DataGrid? I need to get the row and column indexes for the MouseLeftButtonDown event.
It's a bit more complicated than this but the following links should be helpful in getting the index of the row and column.
WPF DataGrid - detecting the column, cell and row that has been clicked: http://blog.scottlogic.com/2008/12/02/wpf-datagrid-detecting-clicked-cell-and-row.html
WPF DataGrid - get row number which mouse cursor is on
You will have to use the VisualTreeHelper class to traverse the Visual elements that make up the DataGrid as explained above.
For those that may wish to avoid my search here is the total code I ended up puzzling together that is able to deliver:
Current row index
Current Column index
Current Column header And
is able to expose the value/s of columns on the row.
The code goes into MouseLeftButtonup event and DGrid1 is the name of the grid
Dim currentRowIndex As Integer = -1
Dim CurrentColumnIndex As Integer = -1
Dim CurrentColumnHeader As String = ""
Dim Myrow As DataRowView = Nothing
Dim dep As DependencyObject = DirectCast(e.OriginalSource, DependencyObject)
While dep IsNot Nothing And Not TypeOf dep Is DataGridCell And Not TypeOf dep Is Primitives.DataGridColumnHeader
dep = VisualTreeHelper.GetParent(dep)
If dep IsNot Nothing Then
If TypeOf dep Is DataGridCell Then
Dim cell As DataGridCell = DirectCast(dep, DataGridCell)
Dim col As DataGridBoundColumn = DirectCast(cell.Column, DataGridBoundColumn)
Myrow = DGrid1.SelectedItem
CurrentColumnHeader = col.Header.ToString
CurrentColumnIndex = col.DisplayIndex
currentRowIndex = DGrid1.Items.IndexOf(DGrid1.CurrentItem)
Exit While
End If
End If
End While
If currentRowIndex = -1 OrElse CurrentColumnIndex = -1 OrElse CurrentColumnHeader = "" OrElse Myrow Is Nothing Then Exit Sub
'code to consume the variables from here
Dim strinwar As String = Myrow.Item("header name or index").ToString()

Return a value that gives the relative position of a GridSplitter in a WPF application

In a WPF application the user can double click a line in a DataGrid to open a new page that contain tabs with grids - some of these have GridSplitters like this
Private Function CentreGrid() As Grid
Try
Dim vGrid As New Grid
For i As Integer = 0 To 2
Dim vCol As New ColumnDefinition
If i = 1 Then
vCol.Width = New GridLength(5, GridUnitType.Auto)
End If
vGrid.ColumnDefinitions.Add(vCol)
Next
Dim vLeftGrid As Grid = LeftGrid()
Grid.SetColumn(vLeftGrid, 0)
vGrid.Children.Add(vLeftGrid)
Dim vGridSplitter As New GridSplitter
With vGridSplitter
.VerticalAlignment = Windows.VerticalAlignment.Stretch
.HorizontalAlignment = Windows.HorizontalAlignment.Center
.ResizeBehavior = GridResizeBehavior.PreviousAndNext
.Background = New SolidColorBrush(Colors.Blue)
.Width = 5
.Margin = New Thickness(5)
End With
Grid.SetColumn(vGridSplitter, 1)
vGrid.Children.Add(vGridSplitter)
Dim vRightGrid As Grid = RightGrid()
Grid.SetColumn(vRightGrid, 2)
vGrid.Children.Add(vRightGrid)
Return vGrid
Catch ex As Exception
EmailError(ex)
Return Nothing
End Try
End Function
As everything is generated dynamically from code-behind is there any method to get a handle on the relative grid position that has been changed by the user so that when the page is closed and another instance opened the GridSplitter can be in the same relative position that the user selected beforehand?
Thanks

WPF - Search for Incremental Numbered Controls using Visual Basic

First time using WPF coming from WinForm and have been adjusting fairly well however I am stumped on one procedure I used quite commonly. This was the code that I used in WinForm to autopopulate controls that were labeled like so; label1, label2, label3, etc..
Dim lbl As Label
Dim matcheslbl() As Control
For i As Integer = 1 To 24
matcheslbl = Me.Controls.Find("label" & i, True)
lbl = DirectCast(matcheslbl(0), Label)
If matcheslbl.Length > 0 AndAlso TypeOf matcheslbl(0) Is Label Then
lbl.Text = "Data Here"
End If
Next
How do I use the same procedure in WPF? My hierarchy layout in the form goes from WrapPanel > StackPanel > Canvas > Controls
After modifying the code to my knowledge I get hung up on the Me.Controls aspect and cant find anything after extensively searching, or im not fully understanding it. This is my modified code...
For i As Integer = 1 To 24
Dim lbl As Label
Dim matcheslbl() As Control
matcheslbl = Me.WrapPanel.FindName("lbl" & i)
lbl = DirectCast(matcheslbl(0), Label)
If matcheslbl.Length > 0 AndAlso TypeOf matcheslbl(0) Is Label Then
lbl.Content = "Data Here"
End If
Next
This hangs up here..
matcheslbl = Me.WrapPanel.FindName("lbl" & i)
Any help on how to accomplish my previous procedure in WPF and give a detailed description on how to achieve it since I am very new to WPF
If you look at the intellisense on Me.WrapPanel.FindName you will notice it does not return an array, just a single object. I fixed your code with the following
For i As Integer = 1 To 24
Dim o As Object = wpMain.FindName("Label" + i.ToString())
DirectCast(o, Label).Content = "Data Here"
Next

Controls added dynamically not visible

I am trying to add controls to WPF Grid dynamically basically to create a suduku layout, I have checked with Visual tree viewer in debug mode, controls are getting added to the Grid, but never updated on UI,
Can you please let me know if i am missing anything.. below is my code
Private Sub MainWindow_Loaded_1(sender As Object, e As RoutedEventArgs)
For _row As Integer = 0 To 9
Dim rowDef As RowDefinition = New RowDefinition()
If _row = 3 Or _row = 6 Then
grdMain.Height = 25
Else
grdMain.Height = 20
End If
grdMain.RowDefinitions.Add(rowDef)
For _col As Integer = 0 To 9
lblProgress.Content = _row.ToString()
System.Threading.Thread.Sleep(100)
Dim colDef As ColumnDefinition = New ColumnDefinition()
If _col = 3 Or _col = 6 Then
grdMain.Width = 25
Else
grdMain.Width = 20
End If
grdMain.ColumnDefinitions.Add(colDef)
Dim tb As TextBox = New TextBox()
tb.Name = "txtBox" & _row.ToString & _col.ToString
tb.Text = tb.Name
Grid.SetRowSpan(tb, 1)
Grid.SetColumnSpan(tb, 1)
grdMain.Children.Add(tb)
Grid.SetRow(tb, _row)
Grid.SetColumn(tb, _col)
Next
Next
Me.Content = grdMain
Me.Show()
End Sub
Haven't tried that before, not sure why you are not using xaml to achieve this.
But, can see essential part missing which is Grid.Row and Grid.Column properties of your label. This is required to position some content in the rows and columns you are creating.
for example, to position tb textbox in row 2 and column 4, you will need to do:
tb.SetValue(Grid.RowProperty,2);
tb.SetValue(Grid.ColumnProperty,4);
or
Grid.SetRow(tb, 2);
Grid.SetColumn(tb, 4);

Resources