User Tools

Site Tools


notes:uwp:examples

Examples

Draw a circle when tapped

Example: Draw a circle at the point where the screen was tapped:

<Page x:Class="TestApp.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <Canvas x:Name="Canvas1" />
    </Grid>
</Page>
using System;
using Windows.Foundation;
using Windows.UI;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Shapes;
 
namespace TestApp
{
    public sealed partial class MainPage : Page
    {
        private const double Radius = 20;
 
        private Random rand = new Random();
        private byte[] rgb = new byte[3];
 
        public MainPage()
        {
            this.InitializeComponent();
        }
 
        protected override void OnTapped(TappedRoutedEventArgs args)
        {
            Point p = args.GetPosition(this);
 
            rand.NextBytes(rgb);
            Color c = Color.FromArgb(0xFF, rgb[0], rgb[1], rgb[2]);
 
            Ellipse circle = new Ellipse
            {
                Width = Radius * 2,
                Height = Radius * 2,
                Fill = new SolidColorBrush(c)
            };
 
            Canvas.SetLeft(circle, p.X - Radius);
            Canvas.SetTop(circle, p.Y - Radius);
            Canvas1.Children.Add(circle);
 
            args.Handled = true;
            base.OnTapped(args);
        }
    }
}

Capture an image from a camera

Method #1:

<Page x:Class="TestApp.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel>
        <Image x:Name="Image1" />
        <Button Content="Capture Image" Click="CaptureImageButton_Click" />
    </StackPanel>
</Page>
using System;
using System.Threading.Tasks;
using Windows.Media.Capture;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
 
namespace TestApp
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }
 
        private async void CaptureImageButton_Click(object sender, RoutedEventArgs e)
        {
            await CaptureImage();
        }
 
        private async Task CaptureImage()
        {
            CameraCaptureUI cameraUI = new CameraCaptureUI();
            BitmapImage image = new BitmapImage();
            Image1.Source = image;
 
            cameraUI.PhotoSettings.AllowCropping = true;
            cameraUI.PhotoSettings.MaxResolution = CameraCaptureUIMaxPhotoResolution.HighestAvailable;
            cameraUI.PhotoSettings.Format = CameraCaptureUIPhotoFormat.Jpeg;
 
            // Wait for a user to capture a photo.
            StorageFile tempFile = await cameraUI.CaptureFileAsync(CameraCaptureUIMode.Photo);
            if (tempFile != null)
            {
                // Transfer the captured photo to a stream.
                IRandomAccessStreamWithContentType stream = await tempFile.OpenReadAsync();
 
                // Pass the stream to a BitmapImage. The BitmapImage is the source of an Image XAML element.
                await image.SetSourceAsync(stream);
 
                // Store the photo in the local folder.
                StorageFolder folder = ApplicationData.Current.LocalFolder;
                var file = await tempFile.CopyAsync(folder, "picture.jpg", NameCollisionOption.ReplaceExisting);
            }
        }
    }
}

Method #2: This method uses SoftwareBitmap which you can use to perform some post-processing on the captured image:

using System;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Graphics.Imaging;
using Windows.Media.Capture;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
 
namespace TestApp
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }
 
        private async void CaptureImageButton_Click(object sender, RoutedEventArgs e)
        {
            await CaptureImage();
        }
 
        private async Task CaptureImage()
        {
            CameraCaptureUI cameraUI = new CameraCaptureUI();
 
            cameraUI.PhotoSettings.CroppedSizeInPixels = new Size(200, 200);
            cameraUI.PhotoSettings.Format = CameraCaptureUIPhotoFormat.Jpeg;
 
            // Wait for a user to capture a photo.
            StorageFile file = await cameraUI.CaptureFileAsync(CameraCaptureUIMode.Photo);
 
            if (file != null)
            {
                IRandomAccessStream stream = await file.OpenReadAsync();
 
                // -or-
                // using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read) { ... }
 
                // The Image control requires that the image source be in the BGRA8 format
                // with pre-multiplied alpha or no alpha channel. We need to create a software
                // bitmap with the desired format.
                BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream); // decode the image file stream
                SoftwareBitmap bitmap = await decoder.GetSoftwareBitmapAsync();
                SoftwareBitmap bitmapBGR8 = SoftwareBitmap.Convert(bitmap, 
                    BitmapPixelFormat.Bgra8, 
                    BitmapAlphaMode.Premultiplied);
 
                SoftwareBitmapSource source = new SoftwareBitmapSource();
                await source.SetBitmapAsync(bitmapBGR8);
                Image1.Source = source;
            }
        }
    }
}

Win10 update: In UWP apps, you can use the SoftwareBitmapSource type as a XAML image source. This lets you pass un-encoded images to the XAML framework to be immediately displayed on screen, bypassing image decoding by the XAML framework.

More information can be found here.

Master/details view

The Master/details view example presents the following techniques:

  • Displaying a master list and a detail panel for an item selected in the list.
  • Two view states using adaptive triggers:
    • Default (wide) state: the master list is located on the left and the details panel on the right.
    • Narrow state: separate pages for the master page and the details page.
  • Preparing a navigation parameter using PageStackEntry when going back to the master page.
  • Page caching through the NavigationCacheMode property.

This example is based on a similar one from the MSDN.

MainPage.xaml

<Page x:Class="TestApp.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      NavigationCacheMode="Enabled"
      xmlns:data="using:TestApp">
 
    <Page.Transitions>
        <TransitionCollection>
            <NavigationThemeTransition />
        </TransitionCollection>
    </Page.Transitions>
 
    <Page.Resources>
        <DataTemplate x:Key="MasterListViewItemTemplate" x:DataType="data:Book">
            <Grid Margin="0,12,0,12">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
 
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
 
                <TextBlock Text="{x:Bind Title}" Style="{ThemeResource BaseTextBlockStyle}" />
                <TextBlock Text="{x:Bind Author}" Grid.Row="1" MaxLines="1" />
            </Grid>
        </DataTemplate>
 
        <DataTemplate x:Key="DetailContentTemplate" x:DataType="data:Book">
            <StackPanel>
                <TextBlock Text="{x:Bind Title}" Margin="0,8" Style="{ThemeResource TitleTextBlockStyle}" />
                <TextBlock Text="{x:Bind Author}" Margin="0,8" Style="{ThemeResource BodyTextBlockStyle}" />
                <TextBlock Text="{x:Bind Description}" Margin="0,8" 
                           Style="{ThemeResource CaptionTextBlockStyle}" />
            </StackPanel>
        </DataTemplate>
    </Page.Resources>
 
    <Grid>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="AdaptiveStates">
                <VisualState x:Name="DefaultState">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="720" />
                    </VisualState.StateTriggers>
                </VisualState>
 
                <VisualState x:Name="NarrowState">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="0" />
                    </VisualState.StateTriggers>
 
                    <VisualState.Setters>
                        <Setter Target="MasterColumn.Width" Value="*" />
                        <Setter Target="DetailColumn.Width" Value="0" />
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
 
        <Grid.ColumnDefinitions>
            <ColumnDefinition x:Name="MasterColumn" Width="320" />
            <ColumnDefinition x:Name="DetailColumn" Width="*" />
        </Grid.ColumnDefinitions>
 
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
 
        <TextBlock Text="Books" Margin="12,8,8,8" Style="{ThemeResource TitleTextBlockStyle}" />
 
        <!-- Master list (left) -->
        <ListView x:Name="MasterListView"
                  ItemsSource="{x:Bind Books}"
            Grid.Row="1"
            ItemContainerTransitions="{x:Null}"
            ItemTemplate="{StaticResource MasterListViewItemTemplate}"
            IsItemClickEnabled="True"
            ItemClick="MasterListView_ItemClick">
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="HorizontalContentAlignment" Value="Stretch" />
                </Style>
            </ListView.ItemContainerStyle>
        </ListView>
 
        <!-- Details section (right) -->
        <ContentPresenter x:Name="DetailContentPresenter"
            Grid.Column="1"
            Grid.RowSpan="2"
            BorderThickness="1,0,0,0"
            Padding="24,0"
            BorderBrush="{ThemeResource SystemControlForegroundBaseLowBrush}"
            Content="{x:Bind MasterListView.SelectedItem, Mode=OneWay}"
            ContentTemplate="{StaticResource DetailContentTemplate}">
            <ContentPresenter.ContentTransitions>
                <!-- This collection is populated in MasterListView_ItemClick -->
                <TransitionCollection />
            </ContentPresenter.ContentTransitions>
        </ContentPresenter>
    </Grid>
</Page>

MainPage.xaml.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Animation;
using Windows.UI.Xaml.Navigation;
 
namespace TestApp
{
    public sealed partial class MainPage : Page
    {
        public ObservableCollection<Book> Books { get; private set; }
 
        private int selectedBookId;
 
        public MainPage()
        {
            this.InitializeComponent();
 
            Books = new ObservableCollection<Book>();
 
            Loaded += (sender, args) =>
            {
                MasterListView.SelectedItem = Books.FirstOrDefault(b => b.Id == selectedBookId);
            };
        }
 
        protected override void OnNavigatedTo(NavigationEventArgs args)
        {
            base.OnNavigatedTo(args);
 
            // The page's state (the Books collection) is kept on the page because we are using caching
            // (NavigationCacheMode is set to Enabled). That's why we need to check if the Books collection
            // has already been populated.
            if (Books.Count == 0)
            {
                var rep = new BookRepository();
                IEnumerable<Book> books = rep.GetBooks();
                foreach (var book in books)
                    Books.Add(book);
            }
 
            if (args.Parameter is Int32)
                selectedBookId = (int)args.Parameter;
        }
 
        private void MasterListView_ItemClick(object sender, ItemClickEventArgs args)
        {
            Book selectedBook = args.ClickedItem as Book;
            selectedBookId = selectedBook.Id;
 
            if (AdaptiveStates.CurrentState == NarrowState)
            {
                // Use the "drill in" transition for navigating from the master page
                // to the detail page.
                Frame.Navigate(typeof(DetailPage), selectedBookId, new DrillInNavigationTransitionInfo());
            }
            else
            {
                // Play the "entrance" animation when the user switches detail items.
                DetailContentPresenter.ContentTransitions.Clear();
                DetailContentPresenter.ContentTransitions.Add(new EntranceThemeTransition());
            }
        }
    }
}

DetailPage.xaml

<Page x:Class="TestApp.DetailPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
 
    <Page.Transitions>
        <TransitionCollection>
            <NavigationThemeTransition />
        </TransitionCollection>
    </Page.Transitions>
 
    <Grid>
        <StackPanel>
            <TextBlock x:Name="TitleTextBlock" Margin="12,8" HorizontalAlignment="Left"
                       Style="{ThemeResource TitleTextBlockStyle}" />
            <TextBlock x:Name="AuthorTextBlock" Margin="12,8" HorizontalAlignment="Left"
                       MaxWidth="560"
                       Style="{ThemeResource BodyTextBlockStyle}"
                       EntranceNavigationTransitionInfo.IsTargetElement="True" />
            <TextBlock x:Name="DescriptionTextBlock" Margin="12,8" 
                       Style="{ThemeResource CaptionTextBlockStyle}" />
        </StackPanel>
    </Grid>
</Page>

DetailPage.xaml.cs

using Windows.UI.Core;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using Windows.UI.Xaml.Media.Animation;
 
namespace TestApp
{
    public sealed partial class DetailPage : Page
    {
        public DetailPage()
        {
            this.InitializeComponent();
        }
 
        protected override void OnNavigatedTo(NavigationEventArgs args)
        {
            base.OnNavigatedTo(args);
 
            // Parameter is the book's Id.
            int bookId = (int)args.Parameter;
 
            // Set data for the current book.
            Book selectedBook = new BookRepository().GetBook(bookId);
            TitleTextBlock.Text = selectedBook.Title;
            AuthorTextBlock.Text = selectedBook.Author;
            DescriptionTextBlock.Text = selectedBook.Description;
 
            var backStack = Frame.BackStack;
            var backStackCount = backStack.Count;
 
            // An interesting way of passing a parameter to the master page.
            // It works fine regardless of a method called: Navigate or GoBack.
            if (backStackCount > 0)
            {
                var masterPageEntry = backStack[backStackCount - 1];
                backStack.RemoveAt(backStackCount - 1);
 
                // Prepare the navigation parameter for the master page.
                var entry = new PageStackEntry(
                    masterPageEntry.SourcePageType,
                    bookId,
                    masterPageEntry.NavigationTransitionInfo);
                backStack.Add(entry);
            }
 
            // Register for hardware and software back request from the system.
            SystemNavigationManager manager = SystemNavigationManager.GetForCurrentView();
            manager.BackRequested += DetailPage_BackRequested;
            manager.AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;
        }
 
        protected override void OnNavigatedFrom(NavigationEventArgs args)
        {
            base.OnNavigatedFrom(args);
 
            SystemNavigationManager manager = SystemNavigationManager.GetForCurrentView();
            manager.BackRequested -= DetailPage_BackRequested;
            manager.AppViewBackButtonVisibility = AppViewBackButtonVisibility.Collapsed;
        }
 
        private void DetailPage_BackRequested(object sender, BackRequestedEventArgs e)
        {
            // Mark event as handled.
            e.Handled = true;
 
            // Use the "drill out" animation when navigating to the master page.
            Frame.GoBack(new DrillInNavigationTransitionInfo());
        }
    }
}

BookRepository.cs

using System.Collections.Generic;
using System.Linq;
 
namespace TestApp
{
    public class Book
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string Author { get; set; }
        public string Description { get; set; }
 
        public override string ToString()
        {
            return $"Book: Id = {Id}, Title = \"{Title}\", Author = {Author}";
        }
    }
 
    public class BookRepository
    {
        public IEnumerable<Book> GetBooks()
        {
            List<Book> books = new List<Book>();
            books.Add(new Book { Id = 1, Title = "AAA", Author = "Author1", Description = "Lorem ipsum..." });
            books.Add(new Book { Id = 2, Title = "BBB", Author = "Author2", Description = "Lorem ipsum..." });
            books.Add(new Book { Id = 3, Title = "CCC", Author = "Author3", Description = "Lorem ipsum..." });
            return books;
        }
 
        public Book GetBook(int id)
        {
            return GetBooks().Single(b => b.Id == id);
        }
    }
}

You can download the entire example as a Visual Studio 2015 project from here.

notes/uwp/examples.txt · Last modified: 2017/03/08 by admin