Upload
ami-fowler
View
231
Download
0
Embed Size (px)
DESCRIPTION
Reminder Wednesday Nov 4 in tutorial (15 min each group) – T04: Horizontal prototype presentation Friday Nov 6 in tutorial (15 min each group) – T02: Horizontal prototype presentation
Citation preview
CPSC 481 – Week #7Sowmya Somanath
ReminderMonday Nov 2 in class – 1. Write-up – redesign rational (i.e. changes from first prototype)2. Screen snapshots3. Grading sheet from handout4. Horizontal prototype presentation freeze
Either email your slides to me ([email protected]) OR submit them on a USB along with your write-up.
Reminder• Wednesday Nov 4 in tutorial (15 min each group) – T04: Horizontal prototype presentation
• Friday Nov 6 in tutorial (15 min each group) –T02: Horizontal prototype presentation
Plan for TodayMore WPF – useful for implementing vertical prototype.Please download Week 7 slides from: http://pages.cpsc.ucalgary.ca/~ssomanat/CPSC481.htm
User Controls
User Controls• User controls pack a set of UI elements.• Useful when repeating same UI patterns• Instead of copy pasting code, you can re-use user controls.
User Controls1. Add a user control to your class. Name it UserControlDemo
User Controls2. Add Elements to your user control<Grid> <Label Content="I am the User Control" HorizontalAlignment="Left" Margin="19,35,0,0" VerticalAlignment="Top" Height="40" Width="271" FontWeight="Bold" FontSize="24"/> <Button Content="OK" HorizontalAlignment="Left" Height="50" Margin="35,117,0,0" VerticalAlignment="Top" Width="223" FontWeight="Bold"/> <Button Content="CANCEL" HorizontalAlignment="Left" Height="53" Margin="35,185,0,0" VerticalAlignment="Top" Width="223" FontWeight="Bold"/> </Grid></UserControl>
User Controls
3. Add below code to MainWindow.xaml
<Grid Name="grid1"> <Grid.RowDefinitions> <RowDefinition Height="40"/> <RowDefinition Height="auto"/> </Grid.RowDefinitions> <Button Name="button1" Grid.Row="0" Content="Show User Control" Click="button1_Click"/></Grid>
User Controls
4. Add below code to MainWindow.cs
private void button1_Click(object sender, RoutedEventArgs e) { UserControlDemo ucdemo = new UserControlDemo(); Grid.SetRow(ucdemo, 1); grid1.Children.Add(ucdemo); }
User Control and Transitions:
Navigation Method
1. Create 3 user controls. Name them: MainMenu, Page 1 and Page 22. Add a Switcher.cs to the project – This class will handle switching between different
user controls
using System.Windows.Controls;
public static MainWindow pageSwitcher;
public static void Switch(UserControl newPage) { pageSwitcher.Navigate(newPage); }
You will need this to use Navigate() method
3. Add the following code to MainWindow.cs
public MainWindow() { InitializeComponent(); Switcher.pageSwitcher = this; Switcher.Switch(new MainMenu()); }
public void Navigate(UserControl nextPage) { this.Content = nextPage; }
4. Design MainMenu, Page 1 and Page 2 to look like this:
5. For MainMenu, Page 1 and Page 2 add the following events
private void Button_Click(object sender, RoutedEventArgs e) { Switcher.Switch(new MainMenu()); }
private void Button_Click_1(object sender, RoutedEventArgs e) { Switcher.Switch(new Page1()); }
private void Button_Click_2(object sender, RoutedEventArgs e) { Switcher.Switch(new Page2()); }
User Control and Transitions: Excercise1
Don’t duplicate this
Solution <Grid Name="grid1"> <Grid.RowDefinitions> <RowDefinition Height="40"/> <RowDefinition Height="auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions>
</Grid.ColumnDefinitions> <Button Name="button1" Grid.Column="0" Content="BACK" Margin="0,0,305,0" Click="button1_Click"/> <Button Name="button2" Grid.Row="0" Content="NEXT" Margin="292,0,0,0"
Click="button2_Click"/> <StackPanel Name="stack1" Grid.Row="1"></StackPanel> </Grid>
Solution private void button1_Click(object sender, RoutedEventArgs e) {
Next _next = new Next(); stack1.Children.Clear(); stack1.Children.Add(_next); }
private void button2_Click(object sender, RoutedEventArgs e) { Back _back = new Back(); stack1.Children.Clear(); stack1.Children.Add(_back); }
User Control and Scroll Viewers:
Excercise2
Create a user control for an email that looks like this:
Solution<Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="389*"/> <ColumnDefinition Width="234*"/> </Grid.ColumnDefinitions>
<Ellipse Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="89" Margin="23,32,0,0" Stroke="Black" VerticalAlignment="Top" Width="89"/>
<Label x:Name="SenderTextblock" Content="Sender" HorizontalAlignment="Left" Height="42" Margin="127,32,0,0" VerticalAlignment="Top" Width="417" Grid.ColumnSpan="2"/>
<Label Content="Body of the email" HorizontalAlignment="Left" Height="42" Margin="127,62,0,0" VerticalAlignment="Top" Width="417" Grid.ColumnSpan="2"/>
<Canvas x:Name="DeleteGroup" Margin="364,12,209,95" Grid.ColumnSpan="2"> <Ellipse Fill="#FFB61D1D" HorizontalAlignment="Left" Height="50" Stroke="Black"
VerticalAlignment="Top" Width="50"/> <Label Content="X" HorizontalAlignment="Left" Height="50" VerticalAlignment="Top" Width="40"
FontSize="24" FontWeight="Bold" Canvas.Left="10" Foreground="White"/> </Canvas>
</Grid>
Create a scroll viewer in MainWindow.xaml:
Solution
<Grid> <ScrollViewer Height="auto"> <StackPanel Name="Emails" Height="auto" Width="auto"></StackPanel> </ScrollViewer>
</Grid>
• Make the Sender a property that can be different in each instance of an email.
• When the delete Button is clicked, the email should be removed from the view.
• Use the scroll viewer in your main window to show 20 emails (using the Email User Control you created)
---- Create a for loop that initializes 20 Email User Controls. ---- To make it easy, initialze the Sender of each email to “Sender” + I
e.g. Sender 0, Sender 1….
Solutionpublic partial class Email : UserControl { private string name; public string Name { get { return name; } set { name = value; this.SenderTextblock.Content = this.name; } }
public Email() { InitializeComponent(); this.DeleteGroup.MouseLeftButtonDown += DeleteGroup_MouseLeftButtonDown; }
void DeleteGroup_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { (this.Parent as Panel).Children.Remove(this); }
}
Solution
public MainWindow() {
InitializeComponent(); for(int i = 0; i < 20; i++) { Email email = new Email(); email.Name = "Sender " + i.ToString(); this.Emails.Children.Add(email); }
}
Styles and Templates: Button
<Window.Resources> <!--Wpf Style and Template--> <!--Changing Button style--> <Style x:Key="myButtonStyle" TargetType="Button"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <!--Change corner radius values to change shape--> <Border Name="border" BorderBrush="DarkGray" BorderThickness="5" CornerRadius="30,0,66,0" Background="Brown"> <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"
Name="buttonpresenter"> </ContentPresenter> </Border> <!--Trigger for mouse event--> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="true"> <Setter TargetName="border" Property="Border.CornerRadius"
Value="30,10,20,10"></Setter> </Trigger> <Trigger Property="IsMouseOver" Value="false"> <Setter TargetName="border" Property="Background“
Value="Gray"></Setter> </Trigger>
</ControlTemplate.Triggers></ControlTemplate>
</Setter.Value> </Setter> </Style></Window.Resources>
Give the style a key you can refer it by
Create this as a resource – window/ user control
<Grid> <Button Style="{StaticResource myButtonStyle}" Content="Button" HorizontalAlignment="Left" Height="154" Margin="54,59,0,0" VerticalAlignment="Top"
Width="396" Click="Button_Click"/></Grid>
• Control Template defines how a control is drawn• Can also include a setter property that can be changed:
<Style x:Key="myButtonStyle" TargetType="Button"> <Setter Property="Background" Value="Orange"/> <Setter Property="Template">
<ControlTemplate TargetType="Button"> <!--Change corner radius values to change shape--><Border Name="border" BorderBrush="DarkGray" BorderThickness="5" CornerRadius="30,0,66,0" Background="{TemplateBinding Background}">
<Button Style="{StaticResource myButtonStyle}" Content="Button" HorizontalAlignment="Left" Height="154" Margin="54,59,0,0" VerticalAlignment="Top" Width="396" Background="Red" Click="Button_Click"/>
Style and Template: Excercise3
Define a template for a button that has default border color of black. Create a button instance that uses the template but changes border color to blue.
Solution <Setter Property="BorderBrush" Value="Black"/>
<Border Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="5" CornerRadius="30,0,66,0">
<Button Style="{StaticResource myButtonStyle}" Content="Button" HorizontalAlignment="Left" Height="154" Margin="54,59,0,0" VerticalAlignment="Top" Width="396" BorderBrush="Blue" Background="Red" Click="Button_Click"/>
List Boxes
Drag a ListBox into the XAML
List Boxes
List Boxes
Click to modify items
List Boxes
Click to addSelect ‘ListBoxItem’
List Boxes
Change content
• Can get the currently-selected index:listbox1.SelectedIndex
ListBox: Excercise4
• Create a listbox like below and change TextBox content based on listbox selection.
• Add ‘SelectionChanged’ event handler.
Solution
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { textbox1.Text = (String)((ListBoxItem)listbox1.SelectedItem).Content;
}
Simple Animation
Add an ellipse to your xaml
Simple animations
<Ellipse Name="ellipse1" Fill="#FFE82828" HorizontalAlignment="Left" Height="118" Margin="264,121,0,0" Stroke="Black" VerticalAlignment="Top" Width="127"/>
Simple animation
• Add this code to the top of your C# file:using System.Windows.Media.Animation;
• Add this inside your user control class before the constructor: private Storyboard myStoryboard;
Simple animation // animate fade in and fade out DoubleAnimation animation = new DoubleAnimation(); animation.From = 1.0; animation.To = 0.0; animation.Duration = new Duration(TimeSpan.FromSeconds(5)); animation.AutoReverse = true; animation.RepeatBehavior = RepeatBehavior.Forever;
myStoryboard = new Storyboard(); myStoryboard.Children.Add(animation); Storyboard.SetTargetName(animation, ellipse1.Name); Storyboard.SetTargetProperty(animation, new PropertyPath(Ellipse.OpacityProperty));
// Use the Loaded event to start the Storyboard. ellipse1.Loaded += new RoutedEventHandler(myEllipseLoaded);
Simple animation
private void myEllipseLoaded(object sender, RoutedEventArgs e) { myStoryboard.Begin(this); }
Simple animations: Excercise5
Change the animation so that the width of the ellipse is animated.
Solution// animate change width DoubleAnimation animation = new DoubleAnimation(); animation.From = 120.0; animation.To = 240.0; animation.Duration = new Duration(TimeSpan.FromSeconds(5)); animation.AutoReverse = true; animation.RepeatBehavior = RepeatBehavior.Forever;
myStoryboard = new Storyboard(); myStoryboard.Children.Add(animation); Storyboard.SetTargetName(animation, ellipse1.Name); Storyboard.SetTargetProperty(animation, new PropertyPath(Ellipse.WidthProperty));
Mouse based Interactions
Add an ellipse to your xaml
Click and Drag
<Ellipse Name="ellipse1" Fill="#FFE82828" HorizontalAlignment="Left" Height="118" Margin="264,121,0,0" Stroke="Black" VerticalAlignment="Top" Width="127"/>
Click and Drag
• Add MouseDown, MouseMove and MouseUp events to the ellipse
Drag and Move bool captured = false;
private void ellipse1_MouseDown(object sender, MouseButtonEventArgs e) { captured = true;
}private void ellipse1_MouseMove(object sender, MouseEventArgs e) { if (captured) { Thickness margin = ellipse1.Margin; margin.Left = e.GetPosition(grid1).X - (ellipse1.Width / 2); margin.Top = e.GetPosition(grid1).Y - (ellipse1.Height / 2); ellipse1.Margin = margin; }
}private void ellipse1_MouseUp(object sender, MouseButtonEventArgs e) { captured = false;
}
Triggers
Triggers• Allow you to change the value of a given property once a certain
condition changes• Allow you to do this entirely in XAML
• Three types:1. Property trigger2. Data trigger3. Event trigger
Property Trigger• Defined by <Trigger> element.• Watches a specific property on the owner control, and whenever that
property has a specific value, it changes other properties.
Property trigger example<TextBlock Text="Hello, styled world!" FontSize="28" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock.Style><Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Blue"></Setter><Style.Triggers>
<Trigger Property="IsMouseOver" Value="True"><Setter Property="Foreground" Value="Red" /><Setter Property="TextDecorations" Value="Underline" />
</Trigger></Style.Triggers>
</Style></TextBlock.Style>
</TextBlock>
Property trigger example• Result:• Underlines and colours the text red on mouse-over.
Data Triggers• Defined by <DataTrigger> element.• Watches a specific property that can be anywhere (not specifically on
the owner control), and whenever that property has a specific value, it changes other properties.
Data Trigger example<CheckBox Name="cbSample" Content="Hello, world?" /><TextBlock HorizontalAlignment="Center" Margin="0,20,0,0" FontSize="48">
<TextBlock.Style><Style TargetType="TextBlock">
<Setter Property="Text" Value="No" /><Setter Property="Foreground" Value="Red" /><Style.Triggers>
<DataTrigger Binding="{Binding ElementName=cbSample, Path=IsChecked}" Value="True">
<Setter Property="Text" Value="Yes!" /><Setter Property="Foreground" Value="Green" />
</DataTrigger></Style.Triggers>
</Style></TextBlock.Style>
</TextBlock>
TriggersData trigger example• Result:• Changes the text to “Yes!” and the text colour to green when the checkbox is
checked.
Event Triggers• Defined by <EventTrigger> element.• Triggers in response to an event being called.• Triggers exactly once that event is called.
Event Trigger example
<TextBlock Name="lblStyled" Text="Hello, styled world!" FontSize="18" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock.Style><Style TargetType="TextBlock">
<Style.Triggers><EventTrigger RoutedEvent="MouseEnter">
<EventTrigger.Actions><BeginStoryboard>
<Storyboard><DoubleAnimation Duration="0:0:0.300" Storyboard.TargetProperty="FontSize" To="28" /></Storyboard>
</BeginStoryboard></EventTrigger.Actions>
</EventTrigger>
...
Event Trigger example...
<EventTrigger RoutedEvent="MouseLeave"><EventTrigger.Actions>
<BeginStoryboard><Storyboard><DoubleAnimation Duration="0:0:0.800" Storyboard.TargetProperty="FontSize" To="18" /></Storyboard>
</BeginStoryboard></EventTrigger.Actions>
</EventTrigger></Style.Triggers>
</Style></TextBlock.Style>
</TextBlock>
Event Trigger• Result:• Animation enlarges the text on mouse-over, and shrinks it back to its original
size on mouse-leave.
Image as a ButtonExercise: Create a button that displays as an image.
Image as a ButtonSolution:<Grid>
<Button Background="Transparent" HorizontalAlignment="Left" Margin="117,84,0,0" VerticalAlignment="Top" Width="361" Height="231">
<Image Name="img1" Stretch="Fill" Source="Testimg.png" Margin="10"/></Button>
</Grid>