UWP hangs when loading Rich Text document as embedded resource - file-io

I'm trying to include some rich text with my app, but the app hangs when trying to load the text.
// Here is the initiating call:
await aboutDialog.ShowAsync();
// This code hangs on the second line
private async void Page_Loaded(object sender, RoutedEventArgs e)
{
var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("XamlSandbox.cities.rtf");
myRichEditBox.Document.LoadFromStream(Windows.UI.Text.TextSetOptions.FormatRtf, stream.AsRandomAccessStream());
}
// This code works OK
private async void Page_Loaded(object sender, RoutedEventArgs e)
{
var picker = new Windows.Storage.Pickers.FileOpenPicker();
var file = await picker.PickSingleFileAsync();
var fileStream = await file.OpenAsync(FileAccessMode.Read);
myRichEditBox.Document.LoadFromStream(Windows.UI.Text.TextSetOptions.FormatRtf, fileStream);
}
I've tried loading the embedded resource into a memory stream and using that, but that hangs too. Any ideas?

Here is how to properly load the embedded resource in UWP:
var rtfUri = new Uri("ms-appx:///cities.rtf");
var file = await StorageFile.GetFileFromApplicationUriAsync(rtfUri);
var stream = file.OpenAsync(FileAccessMode.Read);
myRichEditBox.Document.LoadFromStream(Windows.UI.Text.TextSetOptions.FormatRtf, stream.GetResults());

Related

How to set image.Source via async stream in an UWP application?

I want to set image.Source via async stream in an UWP application. Otherwise the image will flicker when switch to other image source.
My code is as below. And the log shows it works. Certainly I put 2 image files in the corresponding path before I test the demo code.
But in fact I did not see any picture shown, why?
Log:
111111111111 image file path = C:\Users\tomxu\AppData\Local\Packages\a0ca0192-f41a-43ca-a3eb-f128a29b00c6_1qkk468v8nmy0\LocalState\2.jpg
22222222222
33333333333333
4444444444444
The thread 0x6d38 has exited with code 0 (0x0).
The thread 0x6a34 has exited with code 0 (0x0).
111111111111 image file path = C:\Users\tomxu\AppData\Local\Packages\a0ca0192-f41a-43ca-a3eb-f128a29b00c6_1qkk468v8nmy0\LocalState\1.jpg
22222222222
33333333333333
4444444444444
Code:
private async void setImageSource(string imageFilePath)
{
StorageFile sFile = await StorageFile.GetFileFromPathAsync(imageFilePath);
Debug.WriteLine("111111111111 image file path = " + imageFilePath);
Stream fileStream = await sFile.OpenStreamForReadAsync();
Debug.WriteLine("22222222222");
InMemoryRandomAccessStream ras = new InMemoryRandomAccessStream();
Debug.WriteLine("33333333333333");
await fileStream.CopyToAsync(ras.AsStreamForRead());
Debug.WriteLine("4444444444444");
BitmapImage bi = new BitmapImage();
bi.SetSource(ras);
image1.Source = bi;
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
string fullFolder = ApplicationData.Current.LocalFolder.Path;
if (count % 2 == 1)
{
setImageSource(fullFolder + #"\1.jpg");
//image1.Source = new BitmapImage(new Uri(#"ms-appx:///Assets/1.jpg"));
}
else
{
setImageSource(fullFolder + #"\2.jpg");
//image1.Source = new BitmapImage(new Uri(#"ms-appx:///Assets/2.jpg"));
}
count++;
}
Here is an example of how I convert a base64 image string to a BitmapImage..
var ims = new InMemoryRandomAccessStream();
var bytes = Convert.FromBase64String(base64String);
var dataWriter = new DataWriter(ims);
dataWriter.WriteBytes(bytes);
await dataWriter.StoreAsync();
ims.Seek(0);
var img = new BitmapImage();
img.SetSource(ims);
ims.Dispose();
return img;
Try some of the things I'm doing there. Like I notice your code is not setting the seek of the InMemoryReadAccessStream
For your question, I have something to clarify with you.
Your pictures are always in the application data folder. If you want to show it at runtime by programming, the easy way is using the ms-appdata URI scheme to refer to files that come from the app's local, roaming, and temporary data folders. Then, you could use this URL to initialize the BitmapImage object. With this way, you don't need to manually manipulate the file stream.
private void setImageSource(int i)
{
BitmapImage bi = new BitmapImage(new Uri("ms-appdata:///local/"+i+".png"));
image1.Source = bi;
}
private int count = 0;
private void Button_Click(object sender, RoutedEventArgs e)
{
if (count % 2 == 1)
{
setImageSource(1);
}
else
{
setImageSource(2);
}
count++;
}
If you say you have to manipulate the file stream to initialize the BitmaImage, then please add some break points to debug your code. If you add break points to check the InMemoryRandomAccessStream after call CopyToAsync method, you will see that its size is 0. It meant that the file stream has not been wrote to it. To solve this issue, you need to set a buffer size for it. Note: you used ras.AsStreamForRead() method, it's incorrect. You're writing stream to it, so you need to call ras.AsStreamForWrite().
The code looks like the following:
private async void setImageSource(string imageFilePath)
{
StorageFile sFile = await StorageFile.GetFileFromPathAsync(imageFilePath);
using (Stream fileStream = await sFile.OpenStreamForReadAsync())
{
using (InMemoryRandomAccessStream ras = new InMemoryRandomAccessStream())
{
await fileStream.CopyToAsync(ras.AsStreamForWrite((int)fileStream.Length));
ras.Seek(0);
BitmapImage bi = new BitmapImage();
bi.SetSource(ras);
img.Source = bi;
}
}
}
private int count = 0;
private void Button_Click(object sender, RoutedEventArgs e)
{
string fullFolder = ApplicationData.Current.LocalFolder.Path;
if (count % 2 == 1)
{
setImageSource(fullFolder + #"\1.jpg");
}
else
{
setImageSource(fullFolder + #"\2.jpg");
}
count++;
}
In addition, like #visc said, you need to call ras.Seek(0) method to reset the stream to beginning, else the image will not show there.

Windows 8.1 BackgroundUploader with Amazon S3 c# in XAML

Trying to upload files from Windows 8.1 to Amazon s3 in Background. Kindly suggest how can I proceed.
I am using XAML. code Snippet of BackgroundDownloader and BackgroundUploader with Amazon S3 will be a great help.
Please find partial implementation of it below.
public async Task UploadFile(IReadOnlyList<StorageFile> files)
{
basicAwsCredentials = new BasicAWSCredentials(accesskey,secretkey);
List<BackgroundTransferContentPart> parts = new List<BackgroundTransferContentPart>();
for (int i = 0; i < files.Count; i++)
{
BackgroundTransferContentPart part = new BackgroundTransferContentPart("File" + i, files[i].Name);
part.SetFile(files[i]);
parts.Add(part);
}
Uri uri = new Uri(bucketurl+ExistingBucketName+"/");
BackgroundUploader uploader = new BackgroundUploader();
UploadOperation upload = await uploader.CreateUploadAsync(uri, parts);
// Attach progress and completion handlers.
await HandleUploadAsync(upload, true);
}
private async Task HandleUploadAsync(UploadOperation upload, bool start)
{
try
{
CancellationTokenSource cts = new CancellationTokenSource();
Progress<UploadOperation> progressCallback = new Progress<UploadOperation>();
if (start)
{
// Start the upload and attach a progress handler.
await upload.StartAsync().AsTask(cts.Token, progressCallback);
}
else
{
// The upload was already running when the application started, re-attach the progress handler.
await upload.AttachAsync().AsTask(cts.Token, progressCallback);
}
ResponseInformation response = upload.GetResponseInformation();
// Log(String.Format("Completed: {0}, Status Code: {1}", upload.Guid, response.StatusCode));
}
catch (TaskCanceledException)
{
// Log("Upload cancelled.");
}
catch (Exception ex)
{
//LogException("Error", ex);
}
}

Save InkManager images to byte array

I'm new to win8 app programming but has been assigned to write a windows store app to capture customers' signature and save it to SQL Server. After some research I found a great tutorial
http://www.codeproject.com/Articles/416878/Metro-Paint which shows how to draw and save the image locally. My question is how do I use the InkManager class in the tutorial to save the image to byte arrays so that I can save the image to SQLServer? Thanks!
private async void btnSaveWritingAsImage_Click(object sender, RoutedEventArgs e)
{
if (MyInkManager.GetStrokes().Count > 0)
{
try
{
Windows.Storage.Pickers.FileSavePicker SavePicker = new Windows.Storage.Pickers.FileSavePicker();
SavePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.Desktop;
SavePicker.DefaultFileExtension = ".png";
SavePicker.FileTypeChoices.Add("PNG", new string[] { ".png" });
SavePicker.FileTypeChoices.Add("JPG", new string[] { ".jpg" });
StorageFile filesave = await SavePicker.PickSaveFileAsync();
IOutputStream ab = await filesave.OpenAsync(FileAccessMode.ReadWrite);
if (ab != null)
await MyInkManager.SaveAsync(ab);
}
catch (Exception)
{
var MsgDlg = new MessageDialog("Only handwriting can be saved as image.", "Error while saving");
MsgDlg.ShowAsync();
}
}
else
{
var MsgDlg = new MessageDialog("Only handwriting can be saved as image.", "Error while saving");
await MsgDlg.ShowAsync();
}
}
add: (IBuffer.ToArray() is defined in WindowsRuntimeBufferExtensions)
using System.Runtime.InteropServices.WindowsRuntime;
then just do:
var buffer = await FileIO.ReadBufferAsync(image);//replace ab instead of image
var bytes = buffer.ToArray();

i want to save the user input data to a file this is what i have done. the solution execute but the file is not created

private async void submit_comment(object sender, RoutedEventArgs e)
{
String input = txtInput.Text;
//getting the DocumentsLibrary folder where a file is to be created and then creating the example.txt file
//and storing the StorageFile object that is returned:
try
{
StorageFolder storageFolder = KnownFolders.DocumentsLibrary;
StorageFile sampleFile = await storageFolder.GetFileAsync("sample.txt");
//Writing to file
await Windows.Storage.FileIO.WriteTextAsync(sampleFile, input);
}catch(Exception)
{
}
}

Sharing video and photo in metro apps through share charm

i am trying to take a picture and video from within the app and trying to share it through share charm but i am having a problem doing that. After i take the pic ,the share charm says it has trouble sharing the image. This is my code .Can anybody please let me know what i am doing wrong.
namespace Temp
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class Page1 : Page
{
private StorageFile _photo; // Photo file to share
private StorageFile _video; // Video file to share
private async void OnCapturePhoto(object sender, TappedRoutedEventArgs e)
{
var camera = new CameraCaptureUI();
var file = await camera.CaptureFileAsync(CameraCaptureUIMode.Photo);
if (file != null)
{
_photo = file;
DataTransferManager.ShowShareUI();
}
}
private async void OnCaptureVideo(object sender, TappedRoutedEventArgs e)
{
var camera = new CameraCaptureUI();
camera.VideoSettings.Format = CameraCaptureUIVideoFormat.Wmv;
var file = await camera.CaptureFileAsync(CameraCaptureUIMode.Video);
if (file != null)
{
_video = file;
DataTransferManager.ShowShareUI();
}
}
void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
var request = args.Request;
if (_photo != null)
{
request.Data.Properties.Description = "Component photo";
var reference = Windows.Storage.Streams.RandomAccessStreamReference.CreateFromFile(_photo);
request.Data.Properties.Thumbnail = reference;
request.Data.SetBitmap(reference);
_photo = null;
}
else if (_video != null)
{
request.Data.Properties.Description = "Component video";
List<StorageFile> items = new List<StorageFile>();
items.Add(_video);
request.Data.SetStorageItems(items);
_video = null;
}
}
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
DataTransferManager.GetForCurrentView().DataRequested += OnDataRequested;
}
}
In order for your app to share, you must set the Title of the DataPackagePropertySet and at least one of the "SetXXX" methods. If you do not, you'll see the following message when trying to share "There was a problem with the data from ."
So add request.Data.Properties.Title = "Title_of_photo_or_video"; in OnDataRequested event.