Using WPF, it’s great to use declarative XAML, but it’s also great to use dynamic code. With VB’s new XML Features, you can do either.
Below is a sample showing how to use XAMLReader to take XML generated in code and use it to create XAML to present as UI.
The XAMLPanel demonstrates some of the ease of defining UI via XAML, as well as hooking up events. You might want to use the XAML designer in Visual Studio 2008 to get the intellisense for the XAML.
The sample also demonstrates 2 types of WPF animation: how you can make movies repeat forever or animate a Dependency Property like a button’s Width. (Animating the movie (sounds redundant<g>) means to make it repeat after it finishes playing. )
The movie is animated with XAML, and the Button Width property is animated using DoubleAnimation
Use the code in my prior post (Use the DispatcherTimer, Popup and even a movie to enhance your data presentation) as a base, replace the 5 lines and the HandleClick from that sample that create “MyVid” with the snippet below:
If you try to add event handlers or use the x:Code for the dynamic XAML, an error occurs: “Must compile XAML file that specifies events. Line '0' Position '0'.” This makes sense.
<x:Code><![CDATA[
Sub HandleClick(Sender as object, e as RoutedEventArgs)
MsgBox("You Clicked me!")
End Sub
]]></x:Code>
<Code Sample>
Dim MyVid As MediaElement ' For more fun, let's add a movie to the popup tip
Dim cSrcFile = "d:\t.avi" '"c:\windows\media\chimes.wav"
If False Then ' set this to true for the original code
MyVid = New MediaElement
MyVid.MaxHeight = 100
MyVid.MaxWidth = 100
MyVid.Source = New Uri(cSrcFile) ' change to point to your movie file
Else
' define a child StackPanel in XAML
Dim XAMLPanel = _
<StackPanel
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Orientation="Vertical"
Background="Bisque"
>
<Button>Another button</Button>
<CheckBox>Check me</CheckBox>
<ListBox Background="Blue">
<ListBoxItem><!--Let's put a Button inside a ListBoxItem-->
<Button
BorderBrush="Green"
BorderThickness="2"
Background="LightBlue"
>ListBoxItemButton Click Me!</Button></ListBoxItem>
<ListBoxItem>Two</ListBoxItem>
<ListBoxItem><!--Let's put a TabControl inside a ListBoxItem-->
<TabControl>
<TabItem Header="Col1"><Button>are we crazy?</Button></TabItem>
<TabItem Header="Col2">c2</TabItem>
</TabControl>
</ListBoxItem>
</ListBox>
</StackPanel>
Dim sp2 As StackPanel = Windows.Markup.XamlReader.Load(XAMLPanel.CreateReader)
Dim btn2 As Button = sp2.Children(0)
btn2.AddHandler(Button.ClickEvent, New RoutedEventHandler(AddressOf HandleClick))
Dim lb As ListBox = sp2.Children(2)
Dim btn3 As Button = CType(lb.Items(0), ListBoxItem).Content
btn3.AddHandler(Button.ClickEvent, New RoutedEventHandler(AddressOf HandleClick))
sp.Children.Add(sp2)
'now add a movie that repeats. Must use Windows.Media.Animation.StoryBoard
'Use the inline XML feature of VB to create XAML
Dim XAMLMediaElem = _
<MediaElement
Name="MyVid" Height="50.5">
<MediaElement.Triggers>
<EventTrigger RoutedEvent="MediaElement.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<MediaTimeline Source=<%= cSrcFile %>
Storyboard.TargetName="MyVid"
RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</MediaElement.Triggers>
</MediaElement>
MyVid = Windows.Markup.XamlReader.Load(XAMLMediaElem.CreateReader)
' Equivalent of XAML in code:
'Dim tr As New EventTrigger
'MyVid.Triggers.Add(tr)
'tr.RoutedEvent = MediaElement.LoadedEvent
'Dim BeginSB As New Windows.Media.Animation.BeginStoryboard
'tr.Actions.Add(BeginSB)
'Dim Sboard As New Windows.Media.Animation.Storyboard
'BeginSB.Storyboard = Sboard
'Dim medTimeLine As New Windows.Media.MediaTimeline(New Uri(cSrcFile))
'medTimeLine.RepeatBehavior = Windows.Media.Animation.RepeatBehavior.Forever
'Sboard.Children.Add(medTimeLine)
btnTest.Name = "btnTest"
Dim tr = New EventTrigger
tr.RoutedEvent = Button.LoadedEvent
btnTest.Triggers.Add(tr)
Dim BeginSB = New Windows.Media.Animation.BeginStoryboard
tr.Actions.Add(BeginSB)
Dim Sboard = New Windows.Media.Animation.Storyboard
BeginSB.Storyboard = Sboard
Dim dbleAnim = New Windows.Media.Animation.DoubleAnimation
dbleAnim.From = 50
dbleAnim.To = 300
dbleAnim.Duration = New Duration(TimeSpan.FromMilliseconds(200))
dbleAnim.RepeatBehavior = Windows.Media.Animation.RepeatBehavior.Forever
dbleAnim.AutoReverse = True
''Windows.Media.Animation.Storyboard.SetTargetName(dbleAnim, btnTest.Name)
Windows.Media.Animation.Storyboard.SetTargetProperty(dbleAnim, New PropertyPath(Button.WidthProperty))
Sboard.Children.Add(dbleAnim)
End If
sp.Children.Add(MyVid)
Sub HandleClick(ByVal sender As Object, ByVal e As RoutedEventArgs)
Dim b As Button = CType(e.OriginalSource, Button)
b.Content = "Thanks for clicking " + b.Content + DateTime.Now.ToString
'MsgBox("You Clicked me!")
</Code Sample>