WP8 MediaLibrary, view photo in LongListMultiSelector - windows-phone-8

I need to show all photo present in a my device (WP8) in a LongListMultiSelector.
i use this method
MediaPlayer.Queue.ToString();
MediaLibrary mediaLibrary;
PictureAlbum cameraRoll = null;
foreach (MediaSource source in MediaSource.GetAvailableMediaSources())
{
if (source.MediaSourceType == MediaSourceType.LocalDevice)
{
mediaLibrary = new MediaLibrary(source);
PictureAlbumCollection allAlbums = mediaLibrary.RootPictureAlbum.Albums;
foreach (PictureAlbum album in allAlbums)
{
if (album.Name == "Camera Roll")
{
cameraRoll = album;
}
}
}
}
List<BitmapImage> lstBitmapImage = new List<BitmapImage>();
foreach (Picture p in cameraRoll.Pictures)
{
BitmapImage b = new BitmapImage();
b.SetSource(p.GetThumbnail());
lstBitmapImage.Add(b);
}
PhotoHubLLS.ItemsSource = lstBitmapImage;
In a XAML i have this image setting
<Image HorizontalAlignment="Left" Margin="6,6,0,0" Name="image1" Stretch="Fill" VerticalAlignment="Top" Source="{Binding}"/>
It all works perfectly, but I have some questions.
I would like to Zoom on single picture, on image tap i'm insert this code
FrameworkElement fe = sender as FrameworkElement;
if (fe != null)
{
CurrentPicture = fe.DataContext as Picture;
}
but is null a datacontext because I used "Source".
how can I do?

It depends on which event you've wired up. If you're handling the SelectionChanged event, you can retrieve the BitmapImage (not Picture) from the AddedItems collection in the SelectionChangedEventArgs event arguments parameter:
private void LongListSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count > 0)
{
BitmapImage bmp = e.AddedItems[0] as BitmapImage;
}
}
Alternatively if you're handling the Tap event of the Image element in the LongListSelector's ItemTemplate, then you can retrieve the BitmapImage from the sender parameter:
Image imgElement = sender as Image;
BitmapImage bmp = imgElement.Source as BitmapImage;

Related

WriteableBitmapExtension crashes app on device

I have added a WriteableBitmapExtension via NuGet to my Windows Phone 8.1 WinRT app. I have functions to capture an image from camera and save it to picture library. I tried rotate captured image before save and I found solution here
WriteableBitmap crashes program with no message?. Everything works fine on emulator but when I run my app on Nokia Lumia 630 it crashes few seconds after taking a photo without debbuger message. Can anyone help me with this issue? Here is my code of taking photo:
public WriteableBitmap Image
{
get
{
return this.image;
}
set
{
this.image = value;
this.RaisePropertyChanged(() => this.Image);
}
}
private async void TakePhoto()
{
using (var stream = new InMemoryRandomAccessStream())
{
var imgEncodingProperties = ImageEncodingProperties.CreateJpeg();
var img = BitmapFactory.New(640, 480);
await this.MediaCapture.CapturePhotoToStreamAsync(imgEncodingProperties, stream);
stream.Seek(0);
img.SetSource(stream);
WriteableBitmapExtensions.DrawLine(img, 10, 10, 300, 300, Colors.Black);
this.Image = img.Rotate(90);
this.TurnOffCaptureMode();
}
}
private void TurnOffCaptureMode()
{
this.MediaCapture.StopPreviewAsync();
this.IsInCaptureMode = false;
}
Alternate solution is here.
1 Open file Picket use build in camera to take picture.
var openPicker = new FileOpenPicker();
openPicker.ContinuationData["Action"] = "SendPicture";
openPicker.FileTypeFilter.Add(".jpg");
openPicker.FileTypeFilter.Add(".png");
openPicker.PickSingleFileAndContinue();
***2. In app.xaml.cs you will get captured image. as below.***
public void Continue(IContinuationActivatedEventArgs args)
{
if(args.Kind == ActivationKind.PickFileContinuation)
{
var openPickerContinuationArgs = args as FileOpenPickerContinuationEventArgs;
// Recover the "Action" info we stored in ContinuationData
string action = (string) openPickerContinuationArgs.ContinuationData["Action"];
if(openPickerContinuationArgs.Files.Count > 0)
{
// TODO: Get the files here
}
else
{
// TODO: Write code here to handle picker cancellation.
}
}
}

Toggle Button Checked Property Windows Phone 8

I add a toggle button on Windows Phone 8 . When i checked (on), its save a value in Isolated storage and I check that value in constructor whatever it has a toggle value or null. If there is a toggle value I want to display toggle button checked . But I dont know the property to how to checked it when application is run .
Toggle Button XAML :
<toolkit:ToggleSwitch x:Name="toggle" Content="On" Width="165" FontSize="28" VerticalAlignment="Center" HorizontalAlignment="Right"/>
C# :
public Subscription()
{
InitializeComponent();
this.toggle.Checked += new EventHandler<RoutedEventArgs>(toggle_Checked);
this.toggle.Unchecked += new EventHandler<RoutedEventArgs>(toggle_Unchecked);
var appSettings = IsolatedStorageSettings.ApplicationSettings;
if (HasSValue() == "NoValue")
{
// Here i want to Display toggle button unchecked
}
else
{
// Here i want to Display toggle button checked
}
}
void toggle_Unchecked(object sender, RoutedEventArgs e)
{
this.toggle.Content = "Off";
this.toggle.SwitchForeground = new SolidColorBrush(Colors.Red);
var appSettings = IsolatedStorageSettings.ApplicationSettings;
appSettings.Remove("toggleValue");
appSettings.Save();
}
void toggle_Checked(object sender, RoutedEventArgs e)
{
this.toggle.Content = "On";
this.toggle.SwitchForeground = new SolidColorBrush(Colors.Green);
MessageBox.Show("R U Sure ?");
var appSettings = IsolatedStorageSettings.ApplicationSettings;
appSettings.Add("toggleValue", "MAHIN");
appSettings.Save();
}
public string HasSValue()
{
var appSettings = IsolatedStorageSettings.ApplicationSettings;
if (appSettings.Contains("toggleValue"))
{
return (string) appSettings["toggleValue"];
}
else
{
return "NoValue";
}
}
Try this
if (HasSValue() == "NoValue")
{
this.toggle.IsChecked = false;
}
else
{
this.toggle.IsChecked = true;
}
Hope this helps
Update your Constructor as follows
public Subscription()
{
InitializeComponent();
var appSettings = IsolatedStorageSettings.ApplicationSettings;
if (HasSValue() == "NoValue")
{
// Here i want to Display toggle button unchecked
}
else
{
// Here i want to Display toggle button checked
}
this.toggle.Checked += new EventHandler<RoutedEventArgs>(toggle_Checked);
this.toggle.Unchecked += new EventHandler<RoutedEventArgs>(toggle_Unchecked);
}

Display images in observable collection one after the other as user scrolls in windows phone 8

I have a json array of image URLs added into an observable collection and I want to display the first image on the page such that when a user scrolls horizontally, next or previous images in the array shall display on the screen. Help me achieve this.
Here's how I download the image URLs via json and add them to the observable collection
public event PropertyChangedEventHandler PropertyChanged;
private ObservableCollection<readPageModel> readPages = new ObservableCollection<readPageModel>();
public ObservableCollection<readPageModel> Read_Pages
{
get
{
return readPages;
}
set
{
readPages = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("Read_Pages"));
}
}
}
public void DownloadData()
{
WebClient client = new WebClient();
client.DownloadStringCompleted += client_DownloadStringCompleted;
client.DownloadStringAsync(new Uri("http://########/mob/ranges/id/3/limit/10/offset/0/r_id/6", UriKind.Absolute));
}
private void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
try
{
if (!string.IsNullOrEmpty(e.Result))
{
string data = e.Result;
var items = JsonConvert.DeserializeObject<readModel[]>(data);
foreach (var x in items)
{
Read_Pages.Add(x);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
You can take scrollviwer in the xaml after this within this scrollviewer take stack panel with horizontal orientation. and then from c# code add image control to this stack panel.
You can have one image control in content panel and implement below code :
public Page()
{
InitializeComponent();
GestureListener gestureListener = GestureService.GetGestureListener(ContentPanel);
gestureListener.DragCompleted += gestureListener_DragCompleted;
//set the initial image to Image control
}
void gestureListener_DragCompleted(object sender, DragCompletedGestureEventArgs e)
{
// User flicked towards left
if (e.HorizontalVelocity < 0)
{
// Load the next image if Downloaded
}
// User flicked towards right
if (e.HorizontalVelocity > 0)
{
// Load the previous image
}
}
you would also needed to have one variable for tracking the index of image to be loaded

Click to pushpins and display more details of that item in Windows Phone 8

I'm working on a simple map app for windows phone 8. I set multiple pushpins by using windows phone toolkit. I want to show more details info when a pushpin item is tapped.
Here is my code.
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<maps:Map Name="MyMap"
CartographicMode="Road" ColorMode="Light"
LandmarksEnabled="True" PedestrianFeaturesEnabled="True">
<toolkit:MapExtensions.Children>
<toolkit:MapItemsControl Name="allDatas">
<toolkit:MapItemsControl.ItemTemplate>
<DataTemplate>
<toolkit:Pushpin GeoCoordinate="{Binding Coordinate}"
Content="{Binding Name}"
Background="Green"
Foreground="Black"
Tap="Pushpin_Tap"/>
</DataTemplate>
</toolkit:MapItemsControl.ItemTemplate>
</toolkit:MapItemsControl>
</toolkit:MapExtensions.Children>
</maps:Map>
</Grid>
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
ObservableCollection<Data> datas = new ObservableCollection<Data>()
{
new Data() { Coordinate = new GeoCoordinate(22.832991,89.539921), Name = "H", Details = "Hospital", Address = "Address of Hospital" },
new Data() { Coordinate = new GeoCoordinate(22.845489,89.539406), Name = "P", Details = "Fire Station", Address = "Address of Fire"},
new Data() { Coordinate = new GeoCoordinate(22.818019,89.54563), Name = "F", Details = "Police Station", Address = "Address of Police"}
};
ObservableCollection<DependencyObject> children = MapExtensions.GetChildren(MyMap);
var obj = children.FirstOrDefault(x => x.GetType() == typeof(MapItemsControl)) as MapItemsControl;
obj.ItemsSource = datas;
}
private void Pushpin_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
Pushpin pushpin = sender as Pushpin;
if (pushpin.Content != null)
{ //Here i want to show details
MessageBox.Show(pushpin.Content.ToString());
}
}
You can do this:
pushpin.Tap += delegate
{
if (AppSettings["PushpinOpen"] == true)
{
pushpin.Content = attraction.Content;
AppSettings["PushpinOpen"] = attraction.Title;
AppSettings.Save();
}
else
{
pushpin.Content = attraction.Title;
AppSettings.Remove("PushpinOpen");
}
};
You don't have to do it with IsolatedStorageSettings (AppSettings, in this case). You just need to check if the pushpin is already opened, and if it isn't, you can change the content of the pushpin into more detailed information.
private void Pushpin_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
var element = (FrameworkElement)sender;
Data data = (Data)element.DataContext;
MessageBox.Show(data.Address);
}
It may be a little bit late, but I tried to achieve the same. Show more data on pushpin Tap.
I found a working answer here altought it is an answer for a bit different question.

Pause Mediaelement in Windowos phone 8 if user navigates to the other app or homescreen

I had developed application which plays videos using MediaElement with remote url. Everything works fine videos are also playing nicely.
But the problem I am facing is if user is playing video and user touches windows button on phone. Then my app goes to background and home screen is displayed. now on home screen user touches back button. My app is brought to foreground and video starts loading from beginning. Is there anyway by which I can pause mediaelement so that when user comes back to my app video gets resumed.
One more thing is I can not user MediaLauncher since I want to log some events when user interacts with mediacontrols such as play/pause.
Kindly requesting you all to guide me in this scenario.
Thank You.
you can resume your application via ActivationPolicy attribute to the DefaultTask element inActivationPolicy attribute to the DefaultTask element in WMAppManifest.xml and set the value to “Resume”. For this task, you need to edit the app manifest directly instead of using the manifest editor. To do this, right-click WMAppManifest.xml, click Open with, and then choose XML (Text) Editor.
For Resume can be enabled for XAML apps, Direct3D apps, and Direct3D with XAML apps. The following examples show how the DefaultTask element will look for a XAML app and for a Direct3D app.
<DefaultTask Name="_default" NavigationPage="MainPage.xaml" ActivationPolicy="Resume"/>
<DefaultTask Name="_default" ImagePath="PhoneDirect3DApp1.exe" ImageParams="" ActivationPolicy="Resume"/>
app resume for Windows Phone 8
app resume backstack sample
If this will not help you than you can manual paly and stop your video pleyer like bellow code
XAML
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="0.90*"/>
<RowDefinition Height="0.10*"/>
</Grid.RowDefinitions>
<SSME:SmoothStreamingMediaElement x:Name="video" Grid.Row="0" />
<!--TitlePanel contains the name of the application and page title-->
<StackPanel Orientation="Horizontal" Grid.Row="1">
<Button x:Name="PlayButton" Width="150" Click="PlayButton_Click" Loaded="PlayButton_Loaded"/>
<Button x:Name="StopButton" Content="Stop" Width="100" Click="StopButton_Click" />
<TextBlock x:Name="status"/>
<TextBlock x:Name="currentBitrate"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"></Grid>
</Grid>
C# code:
public partial class VIdeoStraming : PhoneApplicationPage
{
string VideoUrl,StreamingUrl;
public VIdeoStraming()
{
InitializeComponent();
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
VideoUrl = this.NavigationContext.QueryString["parameter0"];
string Manifest="/Manifest";
StreamingUrl = VideoUrl + Manifest;
}
private void PlayButton_Click(object sender, RoutedEventArgs e)
{
//Monitor the state of the content to determine the right action to take on this button being clicked
//and then change the text to reflect the next action
switch (video.CurrentState)
{
case SmoothStreamingMediaElementState.Playing:
video.Pause();
PlayButton.Content = "Play";
break;
case SmoothStreamingMediaElementState.Stopped:
case SmoothStreamingMediaElementState.Paused:
video.Play();
PlayButton.Content = "Pause";
break;
}
}
private void PlayButton_Loaded(object sender, RoutedEventArgs e)
{
switch (video.AutoPlay)
{
case false:
PlayButton.Content = "Play";
break;
case true:
PlayButton.Content = "Pause";
break;
}
}
private void StopButton_Click(object sender, RoutedEventArgs e)
{
//This should simply stop the playback
video.Stop();
//We should also reflect the chang on the play button
PlayButton.Content = "Play";
}
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
video.CurrentStateChanged += new RoutedEventHandler(video_CurrentStateChanged);
video.PlaybackTrackChanged += new EventHandler<Microsoft.Web.Media.SmoothStreaming.TrackChangedEventArgs>(video_PlaybackTrackChanged);
//video.SmoothStreamingSource = new Uri("http://64.120.251.114:1945/live/sharedobjects/layoutvideo/mp4:1311370468970.MP4/Manifest");
video.SmoothStreamingSource = new Uri(StreamingUrl);
video.ManifestReady += new EventHandler<EventArgs>(video_ManifestReady);
}
//when use in mobile device
void video_ManifestReady(object sender, EventArgs e)
{
SmoothStreamingMediaElement ssme = sender as SmoothStreamingMediaElement;
if (ssme == null)
{
return;
}
// Select the highest band of tracks which all have the same resolution.
// maxMobileBitrate depends on the encoding settings
const ulong maxMobileBitrate = 1000000;
foreach (SegmentInfo segment in ssme.ManifestInfo.Segments)
{
foreach (StreamInfo streamInfo in segment.AvailableStreams)
{
if (MediaStreamType.Video == streamInfo.Type)
{
List<TrackInfo> widestBand = new List<TrackInfo>();
List<TrackInfo> currentBand = new List<TrackInfo>();
ulong lastHeight = 0;
ulong lastWidth = 0;
ulong index = 0;
foreach (TrackInfo track in streamInfo.AvailableTracks)
{
index += 1;
string strMaxWidth;
string strMaxHeight;
// If can't find width/height, choose only the top bitrate.
ulong ulMaxWidth = index;
// If can't find width/height, choose only the top bitrate.
ulong ulMaxHeight = index;
// V2 manifests require "MaxWidth", while v1 manifests used "Width".
if (track.Attributes.TryGetValue("MaxWidth", out strMaxWidth) ||
track.Attributes.TryGetValue("Width", out strMaxWidth))
{
ulong.TryParse(strMaxWidth, out ulMaxWidth);
}
if (track.Attributes.TryGetValue("MaxHeight", out strMaxHeight) ||
track.Attributes.TryGetValue("Height", out strMaxHeight))
{
ulong.TryParse(strMaxHeight, out ulMaxHeight);
}
if (ulMaxWidth != lastWidth ||
ulMaxHeight != lastHeight)
{
// Current band is now finished, check if it is the widest.
// If same size, current band preferred over previous
// widest, because it will be of higher bitrate.
if (currentBand.Count >= widestBand.Count)
{
// A new widest band:
widestBand = currentBand;
currentBand = new List<TrackInfo>();
}
}
if (track.Bitrate > maxMobileBitrate)
{
break;
}
// Current track always gets added to current band.
currentBand.Add(track);
lastWidth = ulMaxWidth;
lastHeight = ulMaxHeight;
}
if (0 == widestBand.Count &&
0 == currentBand.Count)
{
// Lowest bitrate band is > maxMobileBitrate.
widestBand.Add(streamInfo.AvailableTracks[0]);
}
else if (currentBand.Count >= widestBand.Count)
{
// Need to check the last band which was constructed.
Debug.Assert(currentBand.Count > 0);
widestBand = currentBand; // Winner by default.
}
Debug.Assert(widestBand.Count >= 1);
streamInfo.RestrictTracks(widestBand);
}
}
}
}
void video_PlaybackTrackChanged(object sender, Microsoft.Web.Media.SmoothStreaming.TrackChangedEventArgs e)
{
currentBitrate.Text = e.NewTrack.Bitrate.ToString();
}
void video_CurrentStateChanged(object sender, RoutedEventArgs e)
{
status.Text = video.CurrentState.ToString();
}
private void imghdrleft_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
NavigationService.GoBack();
}
private void imghdrright_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
NavigationService.Navigate(new Uri("/Planet41VIew/Settings.xaml", UriKind.RelativeOrAbsolute));
}
}