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

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.

Related

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

ComboBox array on select event vb.net

Here is my code to add a combobox array to a groupbox array
Dim gbQuoteProduct(5) As GroupBox
Dim cmboBoxQuoteProduct(5) As ComboBox
gbQuoteProduct(n) = New GroupBox
With gbQuoteProduct(n)
.Text = ""
.Location = New Point(10, 5 + n * 70)
.Width = 300
.Height = 70
End With
pnlQuoteProducts.Controls.Add(gbQuoteProduct(n))
cmboBoxQuoteProduct(n) = New ComboBox
With cmboBoxQuoteProduct(n)
.Items.Add("A")
.Items.Add("B")
.Items.Add("C")
.Items.Add("D")
.Text = ""
.Location = New Point(60, 15)
End With
gbQuoteProduct(n).Controls.Add(cmboBoxQuoteProduct(n))
This works fine but I want to add another combobox array to the groupbox array when something is selected from the existing combobox array.
When I try the following:
Private Sub cmboBoxQuoteProduct_SelectedIndexChanged(ByVal sender A
_ Object, ByVal e As System.EventArgs) Handles
_cmboBoxQuoteProduct().SelectedIndexChanged
End Sub
I get the error: "Expected "."" where I have the "()" after cmboBoxQuoteProduct
Any help is much appreciated.
Thanks in advance

create array of existing buttons vb 2013

I used to program in VB6 and am trying to write the same program in VB 2013. In this program I use an array of 49 buttons that all do the same thing when you click on them. I have figured out have to do the click function to a point:
Private Sub Button_Click(sender As Object, e As EventArgs) Handles Button9.Click, Button10.Click, Button11.Click, Button12.Click, Button13.Click, Button16.Click, Button17.Click, Button18.Click, Button19.Click, Button20.Click
...
End Sub
What I am trying to do is simplify the code down to using an array so I can just pass on the index. One other person asked the same question in 2010 and the best answer was:
Button[] array = { firstButton, secondButton };
That would work but I want something with less typing. I also tried the following with failure:
One
Button[] buttons = this.Controls.OfType<Button>().ToArray();
Two
For i = 1 To 100
Dim btns() As Button = Controls.Find("Button" & i, True)
Dim btn As Button
If btns IsNot Nothing Then
btn = btns(0)
'If buttons Is Nothing Then
' ReDim buttons(0)
'Else
' ReDim Preserve buttons(buttons.Length)
'End If
'buttons(UBound(buttons)) = btn
btn.Text = i - 1 'here you can change whatever you want
End If
Next
Three
Dim buttons() As Button
buttons = Nothing
For Each b As Button In Me.Controls
If buttons Is Nothing Then
ReDim buttons(0)
Else
ReDim Preserve buttons(buttons.Length)
End If
buttons(UBound(buttons)) = b
Next
I just can't get it to accept the existing buttons into an array. I hope someone can help.
If your Buttons are nested inside container controls (e.g. a GroupBox) then you will need to perform a recursive search for all buttons. Maybe something like this (totally unoptimized)...
Private Function FindAllButtons(root As Control) As List(Of Button)
Dim result As List(Of Button) = New List(Of Button)()
For Each c As Control In root.Controls
If TypeOf c Is Button Then
result.Add(DirectCast(c, Button))
ElseIf c.HasChildren Then
result.AddRange(FindAllButtons(c))
End If
Next
Return result
End Function
Then just call that in your Form:
Dim allButtons as List(Of Button) = FindAllButtons(Me)
' Add common Click handler
For Each b As Button In allButtons
AddHandler b.Click, AddressOf Button_Click
Next
Update Just for fun, here's a generic version to find other types of control.
Private Function FindAllControls(Of T As Control)(root As Control) As List(Of T)
Dim result As List(Of T) = New List(Of T)()
For Each c As Control In root.Controls
If TypeOf c Is T Then
result.Add(DirectCast(c, T))
ElseIf c.HasChildren Then
result.AddRange(FindAllControls(Of T)(c))
End If
Next
Return result
End Function
You can use that like:
Dim allButtons As List(Of Button) = FindAllControls(Of Button)(Me)
Dim allTextBoxes As List(Of TextBox) = FindAllControls(Of TextBox)(Me)
Option two will work, you just need to add the button found into a list. I suggest you add your buttons into a List(Of ) instead of an array. You can always convert the list into an array if you really need to.
Dim buttonList As New List(Of Button)
For i As Integer = 1 To 100
Dim btns() As Control = Controls.Find("Button" & i, True)
If btns IsNot Nothing AndAlso btns.Length > 0 Then
buttonList.Add(CType(btns(0), Button))
End If
Next

Visual Basic Click Event Adding Scores together

Not 100% sure how to do this, mainly because I am new to programming here!
I have created a table which is populated with random numbers from an array, when the user clicks on one of the buttons the number needs to be added onto their score. eg, when a user clicks 10 and 15, their score will be 25. Once the user has clicked on the button, the button needs to change colour To AliceBlue (just a random colour). Any advice / examples?
This code below makes the table which is used within the game,
Let me know what you think!
Dim RandomNumbers = Enumerable.Range(0, 100).ToList()
Dim RandomNumber As New Random()
For Me.TableColunm = 0 To 4 Step 1
For Me.TableRow = 0 To 4 Step 1
Dim TemporaryNumber = RandomNumbers(RandomNumber.Next(0, RandomNumbers.Count))
RandomNumbers.Remove(CInt(TemporaryNumber))
TableButtons = New Button()
With TableButtons
.Name = "TextBox" & TableColunm.ToString & TableRow.ToString
.Text = TemporaryNumber.ToString
.Width = CInt(Me.Width / 4)
.Left = CInt(TableColunm * (Me.Width / 4))
.Top = TableRow * .Height
.Tag = TemporaryNumber
AddHandler TableButtons.Click, AddressOf TableClickEvent
End With
GameScreen.Controls.Add(TableButtons)
Next TableRow
Next TableColunm
Catch ex As Exception
MsgBox(ex.StackTrace & vbCrLf & "index1= " & TableColunm & vbCrLf & "index2= " & TableRow)
End Try
and
Public Sub TableClickEvent(sender As Object, e As EventArgs)
CType(sender, Button).BackColor = Color.BlueViolet
OverAllScoreInteger += CInt(CType(sender, Button).Tag)
End Sub
I also have to parse the score into a text box called 'UserScoreBox' the form is on 'GameScreen'
You add an eventhandler to a control by using the AddHandler statement and providing the sub that handles the event.
Private Sub Clickhandler(sender As Object, e As EventArgs)
CType(sender, Button).BackColor = Color.AliceBlue
End Sub
Sender is basically the source that initiated the event. In this case the button you clicked.
To make the button raise the event, add this to the code where you create the Buttons:
Addhandler TableButtons.Click, AddressOf Clickhandler
To add the scores you can for example place the index of the table row the button represents to the .Tag property of the button. That way you can, in the event handler, retrieve the row of the sender and add the values.
Edit: Adding the number:
On button creation, save the number in the tag (You could also just use the .Text, but doesn't really matter, it's one conversion less this way):
With TableButtons
.Tag = Temporarynumber
And in the handler unpack the object again:
Overallscore += CInt(CType(sender, button).Tag)

WFP - odd behaviour when opening new tab

The user can select from a DataGrid either by double clicking on the row, or selecting the row and clicking a button.
Using the first method the new page is initialised but the loaded event is not fired.
Using the second method the new page is initialised, the old one fires the unloaded event and the new one fires the loaded event and the new tab opens.
As both the click and doubleclick events are firing the same sub I can't figure out why one works and the other doesn't - when not in debug the new tab is formed using the first method and when clicked the loaded event is then fired, but this doesn't show in debug.
Private Sub Reports_BalanceSheets_EditRecord(sender As Object, e As RoutedEventArgs)
Try
NewRecord = False
Dim DGV As CustomControl.DGVx = Reports_BalanceSheets_Grid.FindName("Reports_BalanceSheets_DGV")
If DGV.SelectedItems.Count = 1 Then
Dim row As System.Data.DataRowView = DGV.SelectedItems(0)
FormID = row("ID")
Dim vName As String = row("Name")
Dim vTab As CustomControl.STC_Tabx = Application.Current.MainWindow.FindName("Reports_BalanceSheetTab")
Dim TabControl As CustomControl.STCx = Application.Current.MainWindow.FindName("AccountingReports_TabControl")
Dim vImageSource As String = ReturnImageAsString("Profit_Loss.png", 16)
If vTab Is Nothing Then
Dim ReportsBalanceSheetFrame As New Frame
Dim Tab As New CustomControl.STC_Tabx
With Tab
.Name = "Reports_BalanceSheetTab"
.Header = " Edit " & vName & " "
.CloseButtonVisibility = DevComponents.WpfEditors.eTabCloseButtonVisibility.Visible
.TabToolTip = "Edit " & vName
.ImageSource = vImageSource
.Content = ReportsBalanceSheetFrame
End With
AddHandler Tab.Closing, AddressOf TabControl_TabClosing
Dim vGrid As Grid = Application.Current.MainWindow.FindName("MainGrid_Website")
RegisterControl(vGrid, Tab, Tab.Name.ToString)
TabControl.Items.Add(Tab)
Dim BalanceSheet As New Reports_BalanceSheet_Page
ReportsBalanceSheetFrame.NavigationService.Navigate(BalanceSheet)
TabControl.SelectedItem = Tab
Else
vTab.Close()
Dim ReportsBalanceSheetFrame As New Frame
Dim Tab As New CustomControl.STC_Tabx
With Tab
.Name = "Reports_BalanceSheetTab"
.Header = " Edit " & vName & " "
.CloseButtonVisibility = DevComponents.WpfEditors.eTabCloseButtonVisibility.Visible
.TabToolTip = "Edit " & vName
.ImageSource = vImageSource
.Content = ReportsBalanceSheetFrame
End With
AddHandler Tab.Closing, AddressOf TabControl_TabClosing
Dim vGrid As Grid = Application.Current.MainWindow.FindName("MainGrid_Website")
RegisterControl(vGrid, Tab, Tab.Name.ToString)
TabControl.Items.Add(Tab)
Dim BalanceSheet As New Reports_BalanceSheet_Page
ReportsBalanceSheetFrame.NavigationService.Navigate(BalanceSheet)
TabControl.SelectedItem = Tab
End If
ElseIf DGV.SelectedItems.Count > 1 Then
AppBoxValidation("You can only select one item at a time to edit!")
Else
AppBoxValidation("You must select an item to edit!")
End If
Catch ex As Exception
EmailError(ex)
End Try
End Sub
Adding e.Handled resolved the issue

Resources