Если вы пропустили предыдущие четыре части, вы можете легко найти их здесь:
- Создание клиента Imgur для Windows Phone — часть 1 — Core & Main Gallery
- Создание клиента Imgur для Windows Phone — часть 2 — бесконечная прокрутка изображений
- Создание клиента Imgur для Windows Phone — часть 3 — просмотр сведений об изображении
- Создание клиента Imgur для Windows Phone — Часть 4 — Аутентификация
В предыдущей статье я говорил о создании механизма загрузки. Теперь я собираюсь поговорить о создании рабочего процесса пользовательского интерфейса, необходимого для создания удобной процедуры загрузки.
Я создаю новую страницу загрузки ( UploadPage.xaml ), которая позволяет пользователю выбрать изображение из библиотеки мультимедиа, а также при необходимости создать новую. Не только это, но я также даю пользователю возможность ввести название и описание изображения, даже если они не являются обязательными.
Полный XAML выглядит так:
<phone:PhoneApplicationPage
x:Class="Imagine.UploadPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d"
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
shell:SystemTray.IsVisible="False">
<!--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-->
<StackPanel Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="UPLOAD IMAGE" Style="{StaticResource PhoneTextNormalStyle}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid.RowDefinitions>
<RowDefinition Height="230"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Image Stretch="UniformToFill" x:Name="imgPreview" Margin="12,12,12,12"></Image>
<Button x:Name="btnPick" Click="btnPick_Click_1">
<Image Source="/Images/photocapture.png"></Image>
</Button>
<StackPanel Grid.Row="1">
<TextBlock Style="{StaticResource PhoneTextTitle3Style}">Name:</TextBlock>
<TextBox x:Name="txtName"></TextBox>
<TextBlock Style="{StaticResource PhoneTextTitle3Style}">Description:</TextBlock>
<TextBox x:Name="txtDescription" TextWrapping="Wrap" AcceptsReturn="True"
TextOptions.TextHintingMode="Animated" Height="210"></TextBox>
</StackPanel>
</Grid>
<Grid Visibility="Collapsed" Grid.RowSpan="2" x:Name="grdUploading">
<Grid.Background>
<SolidColorBrush Color="Black"></SolidColorBrush>
</Grid.Background>
<TextBlock Text="Uploading..." HorizontalAlignment="Center"
VerticalAlignment="Center"></TextBlock>
<toolkit:PerformanceProgressBar IsIndeterminate="True" Margin="0,80,0,0"></toolkit:PerformanceProgressBar>
</Grid>
</Grid>
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar>
<shell:ApplicationBarIconButton x:Name="btnUpload" Click="btnUpload_Click_1" Text="ok" IconUri="/Images/appbar.check.png"></shell:ApplicationBarIconButton>
<shell:ApplicationBarIconButton x:Name="btnCancel" Click="btnCancel_Click_1" Text="cancel" IconUri="/Images/appbar.cancel.png"></shell:ApplicationBarIconButton>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
</phone:PhoneApplicationPage>
Чтобы сделать краткий обзор, вот как это выглядит в результате:
Основная рабочая сетка разделена на две части — компонент предварительного просмотра изображения, поверх которого расположен элемент управления Button , и мета-область, предназначенная для указания имени и описания загружаемого изображения.
Элемент управления изображением за кнопкой будет отображать выбранный контент. В то же время основной фон сетки (для LayoutRoot ) также будет отображать выбранное изображение, хотя и в гораздо большем формате. Все это делается с помощью PhotoChooserTask :
PhotoChooserTask task = new PhotoChooserTask() { ShowCamera = true };
task.Completed += (s, d) =>
{
if (d.TaskResult == TaskResult.OK)
{
byte[] buffer = new byte[16 * 1024];
using (MemoryStream stream = new MemoryStream())
{
int read = 0;
while ((read = d.ChosenPhoto.Read(buffer, 0, buffer.Length)) > 0)
{
stream.Write(buffer, 0, read);
}
BitmapImage image = new BitmapImage();
image.SetSource(stream);
imgPreview.Source = image;
ImageBrush brush = new ImageBrush();
brush.ImageSource = image;
LayoutRoot.Background = brush;
brush.Opacity = .2;
brush.Stretch = Stretch.UniformToFill;
ImageContent = stream.ToArray();
}
}
};
task.Show();
ImageContent — это общий байтовый буфер, который будет использоваться, если пользователь хочет загрузить выбранное изображение. Как только выбор сделан, пользовательский интерфейс будет выглядеть так:
Вот фрагмент кода, который активирует загрузку:
grdUploading.Visibility = System.Windows.Visibility.Visible;
this.ApplicationBar.IsVisible = false;
App.ServiceClient.UploadImage(ImageContent, txtName.Text, txtDescription.Text, (n, image) =>
{
if (n)
{
Dispatcher.BeginInvoke(() =>
{
Clipboard.SetText(image.Image.Link);
MessageBox.Show("Your image was uploaded. The link is placed in the clipboard.",
"Image Upload", MessageBoxButton.OK);
if (NavigationService.CanGoBack)
NavigationService.GoBack();
});
}
else
{
Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("There was an error uploading the image. Please try again later.",
"Image Upload", MessageBoxButton.OK);
});
}
Dispatcher.BeginInvoke(() =>
{
grdUploading.Visibility = System.Windows.Visibility.Collapsed;
this.ApplicationBar.IsVisible = true;
});
});
Когда пользователи принимают изображение, наложение блокирует весь пользовательский интерфейс, чтобы показать, что идет загрузка:
Настраиваемое действие, которое передается в UploadImage, будет вызвано двумя аргументами — логическим флагом, показывающим, была ли загрузка успешной или нет, и десериализованным экземпляром ImgurAtomicImageData . Если первый аргумент равен true, тогда я устанавливаю URL изображения в буфер обмена, чтобы пользователь мог поделиться им при необходимости. Если загрузка не удалась, пользователю сообщают об этом.
Вы можете скачать текущий исходный код проекта здесь . Не забудьте указать свой ключ API и секрет.


