Kövesd a MoDev-etGoogle+ -on
Habár a WP7 rengeteg beépített controllal rendelkezik, az egyedi alkalmazások fejlesztésénél jogosan merül
fel az igény egyedi kontrollok készítésére. Ezért gondoltam, hogy az első példakódnál egy ilyen megvalósítását mutatom be.
Cél: Szeretnénk egy UserControl-t, melynek segítségével egy Lista elrendezésű galériát valósíthatunk meg.
Ha nyomva tartjuk az ujjunkat egy képen akkor felnagyítódik.
Habár a WP7 rengeteg beépített controllal rendelkezik, az egyedi alkalmazások fejlesztésénél jogosan merül
fel az igény egyedi kontrollok készítésére. Ezért gondoltam, hogy az első példakódnál egy ilyen megvalósítását mutatom be.
Cél: Szeretnénk egy UserControl-t, melynek segítségével egy Lista elrendezésű galériát valósíthatunk meg.
Ha nyomva tartjuk az ujjunkat egy képen akkor felnagyítódik.
Ez lesz az eredmény:
- Új projekt
Első lépésben Visual Studio-ban hozzunk létre egy új WP7 projektet. A listában az első Windows
Phone Application-t válasszuk ki. A kérdésre, hogy milyen verziójú projectet szeretnénk válasszuk az
OS 7.1 (Mango) opciót.
- Expression Blend, új user control
Itt ez a látvány fogad minket:
A kezdőoldalunkat látjuk, melyről gyorsan távolítsuk el a Visual Studio által elhelyezett title és
contetn panelt. erre azért van szükség, hogy a leendő listánk az egész képernyőt birtokolja.
Most adjunk hozzá egy új User Controlt az projecthez. Ezt a File/New Item menüpont alatt tehetjük
meg. Itt válasszuk a Usercontrolt, majd adjunk a StretchingImageControl nevet neki.
Ezután letrejön az új control-unk, egy külön XAML fájban, és legenerálódik hozzá a C# objektum is
Állítsuk a UserControl méretét auto-ról 480x100-asra, ez ahhoz kell hogy a későbbi skálázás során
hozzá alklamazkodva nyúljanak a benne lévő elemek.
Adjunk hozzá egy négyzetet, malynek méretezése automatikus legyen, illetve az alingmentjei mind
horizontálisan, mind vertikálisan Strech-re legyenek állítva.
Most adjuk, hozzá a kép címét megjelenítő TextBlock-ot amit a négyzet aljában helyezünk el.
Ez XAML-ben így fog kinézni:
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="ExpandingGallery.StretchingImageControl" d:DesignWidth="480" Width="480" Height="100"> <Grid x:Name="LayoutRoot" Background="Transparent"> <Rectangle Stroke="Black"> <Rectangle.Fill> <ImageBrush Stretch="None"/> </Rectangle.Fill> </Rectangle> <TextBlock Margin="4,0,8,4" TextWrapping="Wrap" Text="TextBlock"
FontSize="45.333"VerticalAlignment="Bottom" d:LayoutOverrides="Width, HorizontalMargin"
Expression Blendben pedig így:
Fontos, hogy a Rectangle/ImageBrush Stretch property-je None-ra legyen állítva, ennek köszönhetően
majd csak egy szeletet látunk a képből.
Ez így nagyon Metrós lesz :)
- Control animációi:
A Control megjelenítési állapotait VisualState-ekben tudjuk megadni. Az átmeneteket ezen State-ek
között fogjuk definiálni, és a képernyőérintés eseményeihez fogjuk hozzárendelni a későbbiekben.
Elsőnek jöjjön a XAML aztán a magyarázat:
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" x:Name="userControl" mc:Ignorable="d" x:Class="ExpandingGallery.StretchingImageControl" d:DesignWidth="480" Width="480" Height="100"> <Grid x:Name="LayoutRoot" Background="Transparent"> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualStateGroup.Transitions> <VisualTransition From="Normal" GeneratedDuration="0" To="Pressed"> <VisualTransition.GeneratedEasingFunction> <BackEase EasingMode="EaseIn"/> </VisualTransition.GeneratedEasingFunction> <Storyboard> <DoubleAnimationUsingKeyFrames
Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="this"><EasingDoubleKeyFrame KeyTime="0" Value="100"/> <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="800"/> </DoubleAnimationUsingKeyFrames> </Storyboard> </VisualTransition> <VisualTransition From="Pressed" GeneratedDuration="0" To="Normal"> <VisualTransition.GeneratedEasingFunction> <BackEase EasingMode="EaseIn"/> </VisualTransition.GeneratedEasingFunction> <Storyboard> <DoubleAnimationUsingKeyFrames
Storyboard.TargetProperty="(FrameworkElement.Height)"
Storyboard.TargetName="this">
<EasingDoubleKeyFrame KeyTime="0" Value="800"/> <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="100"/> </DoubleAnimationUsingKeyFrames> </Storyboard> </VisualTransition> <VisualTransition GeneratedDuration="0"/> </VisualStateGroup.Transitions> <VisualState x:Name="Normal"> <Storyboard/> </VisualState> <VisualState x:Name="Pressed"> <Storyboard> <DoubleAnimation Duration="0" To="800" Storyboard.TargetProperty="(FrameworkElement.Height)"
Storyboard.TargetName="this" d:IsOptimized="True"/>
</Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <Rectangle Stroke="Black"> <Rectangle.Fill> <ImageBrush Stretch="None"/> </Rectangle.Fill> </Rectangle> <TextBlock Height="67" Margin="0,33,8,0" TextWrapping="Wrap"
Text="TextBlock" VerticalAlignment="Top" FontSize="56" d:LayoutOverrides="VerticalAlignment"/>
</Grid> </UserControl>
Létrehoztunk egy VisualStateManager-t amiben egy Groupot vettünk fel, itt lettek elhelyezve a Pressed
és a Normal state közötti animációk (átmenetek). Ez ExpressionBlend GUI-ban nagyon könnyen
összekattintgatható. Kézzel XAML-ben leírni... nem tanácsos... - Eseménykezelők, és az adatkötés előkészítése a controlunkon...
Térjünk vissza VisualStudioba és nyissuk meg a StretchingImageControl.xaml.cs -t. Itt hozzá fogunk
adni új DependencyProperty-ket a controlunk-hoz. Ennek köszönhetően XAML-ben tudunk ezen
property-kkel dolgozni vagy akár adatkötni.
Emellett a konstruktorban beállítjuk a kiindulási VisualState-et, ezutén pedig létrehozzuk az
eseménykezelőket amik az érintés esetén fognak reagálni.namespace ExpandingGallery { public partial class StretchingImageControl : UserControl { //Creating dep props, for the title and the source path public static readonly DependencyProperty TitleProperty = DependencyProperty.Register("ImageTitle", typeof(string), typeof(StretchingImageControl), new PropertyMetadata(null)); public static readonly DependencyProperty ImageSourceProperty = DependencyProperty.Register("ViewImage", typeof(string), typeof(StretchingImageControl), new PropertyMetadata(null)); public StretchingImageControl() { // Required to initialize variables InitializeComponent(); VisualStateManager.GoToState(this, "Normal", true); } public string Title { get { return (string)GetValue(TitleProperty); } set { SetValue(TitleProperty, value); } } public string ImageSource { get { return (string)GetValue(ImageSourceProperty); } set { SetValue(ImageSourceProperty, value); } } private void this_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { VisualStateManager.GoToState(this, "Pressed", true); } private void this_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { VisualStateManager.GoToState(this, "Normal", true); } private void this_MouseLeave(object sender, MouseEventArgs e) { VisualStateManager.GoToState(this, "Normal", true); } } }
Ahhoz hogy meghívódjanak az eseménykezelők, természetesen a XAML-ben is fel kell őket tüntetni.
Ezt megtesszük a UserControl nyitó tag-ben:<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="ExpandingGallery.StretchingImageControl" d:DesignWidth="480" Width="480" Height="100" x:Name="this" MouseLeave="this_MouseLeave" MouseLeftButtonUp="this_MouseLeftButtonUp"
MouseLeftButtonDown="this_MouseLeftButtonDown">
Ezután a Rectangle és a Textbox megfelelő tulajdonságait hozzá kell kötnünk a Control osztály
propertieihez.... <Rectangle Stroke="Black"> <Rectangle.Fill> <ImageBrush Stretch="None" ImageSource="{Binding ViewImage, ElementName=this}"/> </Rectangle.Fill> </Rectangle> <TextBlock Margin="4,0,8,4" TextWrapping="Wrap" Text="{Binding ImageTitle,
ElementName=this}"
...
- MainPage kialakítása, Lista hozzákötése saját adatforráshoz.
Saját adatforrás - A listánkat egy kollekcióhoz fogjuk kötni, mely két, a mi controlunkhoz illeszkedő
property-vel rendelkezik. Ehhez először létrehozunk egy osztályt mely az elemhez tartozó adatokat
tárolja.public class GalleryImages { public string image { get; set; } public string ButtonText { get; set; } }
Adjunk egy ListBox-ot a MainPage-ünkhöz, mely töltse ki a teljes képernyőt.
A listBox-hoz adjunk hozzá egy DataTemplate-et mely a kollekció eleminek megjelenítését írja le.
Itt az oldal elején a névtérhez hozzáadott saját control-unkat illesszük be, és a Title illetve az
ImageSource property-nek adjuk meg a megfelelő binding értékeket...<phone:PhoneApplicationPage ..... xmlns:local="clr-namespace:ExpandingGallery" ..... <!--LayoutRoot is the root grid where all page content is placed--> <Grid x:Name="LayoutRoot" Background="Transparent"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <!--TitlePanel contains the name of the application and page title--> <!--ContentPanel - place additional content here--> <Grid x:Name="ContentPanel" Grid.RowSpan="2"> <ListBox Name="StretchingGallery" Width="480"> <ListBox.ItemTemplate> <DataTemplate> <local:StretchingImageControl VerticalAlignment="Top"
Title="{Binding ButtonText}" Height="100" Width="480"
</DataTemplate> </ListBox.ItemTemplate> </ListBox> </Grid> </Grid> </phone:PhoneApplicationPage>
Menjünk át a MainPage.xaml.cs-be és hozzuk létre a kollekciót, majd töltsük fel pár elemmel.
Ezek után kössük rá a ListBox-unk DataSource-ára (A képek amikre hivatkozok, benne vannak a
letölthető Solution-ben)namespace ExpandingGallery { public partial class MainPage : PhoneApplicationPage { ObservableCollection<GalleryImages> ButtonList; public MainPage() { InitializeComponent(); ButtonList = new ObservableCollection<GalleryImages>(); ButtonList.Add(new GalleryImages { image = "1.jpg", ButtonText = "Excitement" }); ButtonList.Add(new GalleryImages { image = "2.jpg", ButtonText = "Perfection" }); ButtonList.Add(new GalleryImages { image = "3.jpg", ButtonText = "Elegance" }); ButtonList.Add(new GalleryImages { image = "4.jpg", ButtonText = "Randomness" }); StretchingGallery.ItemsSource = ButtonList; } } }
Ezzel el is készültünk.....
A kész Solution innen elérhető:
Nincsenek megjegyzések:
Megjegyzés küldése