In Silverlight 2, all Xaml controls are isomorphic with CLR objects. That is, anything you can create in Xaml you can create in code.
Where you might write,
You can also write
dim myButton as New Button();
myButton.Content = "Hello"; While it is possible to create all your controls and objects in code, best practices dictate that it is usually better to do so in Xaml. The most compelling reason is that Xaml is highly "toolable" - that is, it lends itself to round-trip modification in tools such as Visual Studio and Expression and thus is easier to scale, modify and maintain.
On the other hand, there are times that you can't know at design time which or how many objects you'll need, and the ability to create objects dynamically can be a fundamental requirement.
We can make a minor modification to our existing program to add another button on the user's request. Add the following button to the Xaml file (note that we also name the canvas!)
<Canvas x:Name="myCanvas">
<Button x:Name="myButton" Content="Hello"
Canvas.Left="10" Canvas.Top="10"/>
<Button x:Name="Another" Content="Add Another"
Canvas.Left="10" Canvas.Top="50" />
<CheckBox x:Name="rushOrder" Content="Rush"
Canvas.Left="50" Canvas.Top="10" />
The effect is to add a button to the page with the words "Add Another." When the user clicks on this button, we want to add a button to the UI and we want that button to have its own size, position and behavior.
We do all of that in the code behind.
Creating a Button Dynamically
Save the .xaml file and open Page.xaml.vb
The first thing to do is to add an event handler for the new button,
AddHandler Another.Click, AddressOf Another_Click And to add its implementation, in which you'll create a new button and set its properties,
Private Sub Another_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
Dim b As New Button()
b.Content = "I live!"
b.SetValue(Canvas.LeftProperty, 10.0)
b.SetValue(Canvas.TopProperty, Me.newButtonPosition)
Me.newButtonPosition += 30.0
b.Width = 100
b.Height = 20
AddHandler b.Click, AddressOf new_button_click
myCanvas.Children.Add(b)
End Sub Because the canvas's Left and Top are not actually properties of the Button (but are extended properties) you set them with the SetValue method, which takes two parameters. The first is the actual name of the property you want to set (Canvas.LeftProperty and Canvas.TopProperty) which is not difficult to find as Intellisense will supply it) and the second is the value (in this case a double).
Because I want to be able to click this button more than once, and I don't want the new buttons overwriting each other, I need a member variable to keep track of the top value,
private newButton as double = 100.0; After I set it, I can then increment it so the next button will fall below the previous,
b.SetValue(Canvas.TopProperty, Me.newButtonPosition)
Me.newButtonPosition += 30.0 The result is very satisfying,
Figure 1-14. Adding Dynamic Buttons
The second thing to notice about the Button we are adding is that we are also adding an event handler registration,
AddHandler b.Click, AddressOf new_button_click This means that every button that is added (each of the three shown in Figure 1-8) is registered to call new_button_click when it is clicked. You'll need to write that event handler into your Page.xaml.cs file,
Private Sub new_button_click(ByVal sender As Object, ByVal e As RoutedEventArgs)
Dim btn As Button = TryCast(sender, Button)
btn.Content = "Don't do that!"
btn.IsEnabled = False
End Sub
As the buttons are clicked, they change their message and become disabled,
Figure 1-15. Disabled Dynamic Buttons
Finally, none of this will work if you don't add the buttons to the page. In this case, however, you don't want to add them to LayoutRoot as their positioning is in terms of a specific canvas, so you'll add them to that canvas,
myCanvas.Children.Add(b); When you run the program, they are members of that canvas, just as surely as if you had added them individually in the Xaml file.
No comments:
Post a Comment