I'm making a Windows 8 Metro Style test application using XML files. I have the reading of the file and nodes working including editing and deleting them.
The problem I'm facing now and can't figure out how to complete is the adding of a node.
Below here is the code I'm using for reading and saving.
private static async System.Threading.Tasks.Task<XmlDocument> LoadXML()
{
StorageFolder storageFolder = ApplicationData.Current.RoamingFolder;
StorageFile storageFile = await storageFolder.GetFileAsync("Settings.xml");
var XmlFile = await XmlDocument.LoadFromFileAsync(storageFile);
return XmlFile;
}
private static async System.Threading.Tasks.Task SaveXML(XmlDocument XmlFile)
{
StorageFolder storageFolder = ApplicationData.Current.RoamingFolder;
StorageFile storageFile = await storageFolder.GetFileAsync("Settings.xml");
await XmlFile.SaveToFileAsync(storageFile);
MessageDialog Message = new MessageDialog("Data is saved/removed!", "Notification");
await Message.ShowAsync();
}
This part below is of an event which refers to the two above. In this part of the code do I need to add a new node based on information from a textbox.
private async void btnSaveproject_Click(object sender, RoutedEventArgs e)
{
var XmlFile = await LoadXML();
await SaveXML(XmlFile);
}
For those who wonder how I have done the removing and editing will I also add these part of the code right below here.
// Removing
IXmlNode Node = XmlFile.SelectSingleNode("XML").SelectSingleNode("List").SelectSingleNode(lvList.SelectedItem.ToString());
XmlFile.SelectSingleNode("XML").SelectSingleNode("List").RemoveChild(Node);
//Saving
XmlFile.SelectSingleNode("XML").SelectSingleNode("Colors").SelectSingleNode("ColorR").InnerText = tbxColorR.Text;
Related
I am trying to play a sound with audio graph and it is failing on creating a file output node from a storage file. I have checked and the storage file is not null; The error I am getting is just unknown error and is of no help
Any ideas?
private async void HandlePlayCommand()
{
if (_audioGraph == null)
{
var settings = new AudioGraphSettings(AudioRenderCategory.Media);
var createResults = await AudioGraph.CreateAsync(settings);
if (createResults.Status != AudioGraphCreationStatus.Success) return;
_audioGraph = createResults.Graph;
var deviceResult = await _audioGraph.CreateDeviceOutputNodeAsync();
if(deviceResult.Status != AudioDeviceNodeCreationStatus.Success) return;
var outputNode = deviceResult.DeviceOutputNode;
StorageFile file = await GetStorageFiles();
var fileResult = await _audioGraph.CreateFileInputNodeAsync(file);
if (fileResult.Status != AudioFileNodeCreationStatus.Success) return;
var fileInputNode = fileResult.FileInputNode;
fileInputNode.AddOutgoingConnection(outputNode);
_audioGraph.Start();
}
}
private async Task<StorageFile> GetStorageFiles()
{
string CountriesFile = #"Assets\909_1.aif";
StorageFolder InstallationFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
StorageFile file = await InstallationFolder.GetFileAsync(CountriesFile);
return file;
}
By testing on my side, I'm afraid the .aif format currently is not supported by AudioGraph.CreateFileInputNodeAsync method. The formats sure to be supported that are .mp3,.wav,.wna,.m4a and so on. So the solution maybe change the audio files to other formats.
More details please reference the audio official sample.
So im making a windows store app that you select a file with one button, via file picker, then with another button it processes that file but im having trouble getting the selected file to processing method.
Since the Picker sets one of my text blocks to the path of the file to be displayed for the user i've tried using:
StorageFile file = await StorageFile.GetFileFromPathAsync(fullFilePath.Text);
But due to Windows RT limitations I just get access it denied from most locations
Any other suggestions on what to try?
First button click:
private async Task getFile()
{
FileOpenPicker openPicker = new FileOpenPicker();
openPicker.ViewMode = PickerViewMode.List;
openPicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
openPicker.FileTypeFilter.Add(".txt");
StorageFile file = await openPicker.PickSingleFileAsync();
if (file != null)
{
fullFilePath.Text = file.Path;
}
else
{
updateStatus("File Selection cancelled.");
}
}
Second button start this but needs to use the file from above
private async Task processFile()
{
...
string content = await FileIO.ReadTextAsync(file);
...
}
Make the StorageFile a field in your class:
class MyClass
{
StorageFile m_pickedFile;
async Task GetFile()
{
// Setup the picker...
m_pickedFile = await openPicker.PickSingleFileAsync();
// Show the path to the user...
}
async Task ProcessFile()
{
if (m_pickedFile != null)
{
// now use m_pickedFile...
}
}
}
public static async Task Store(ObservableCollection<Product> list)
{
Uri path = new Uri("ms-appx:///ListCollection.json");
var store = await StorageFile.GetFileFromApplicationUriAsync(path);
var stream = File.OpenWrite(store.Path);
var serialize = new DataContractJsonSerializer(typeof(ObservableCollection<Product>));
serialize.WriteObject(stream, list);
}
Ok this is the piece of code that I used to serialize a collection , works very well , no problem with it , but what I want and tried and no success. I created a JSON file in my project. I want to store and stream data to that file. I tried some methods but no success , how do I open a stream to a file that is currently in my project?
EDITED : Commented the code that was working and wrote what I intend to do. Thanks for support.
When I get to this line
var stream = File.OpenWrite(store.Path); it says that is inaccesible.
What I intend to do is serialize some data to a file called ListCollection.json that is emtpy , that file is project file. It might be the stream or it might be the file that gives me that error. No idea.
My guess is that your project file is located in the installation directory of your application and as far as I know you can't just write to that directory.
You would have to put a deployment action in your solution that writes the desired project file to the application data directory. There you should be able to write it.
I looked through some of the documentation and came accross this:
MSDN
The app's install directory is a read-only location.
I found a Link which makes use of a little hack or so it seems.
I am not sure if this will work if the application is deployed etc.
but you can try this to write the file.
I am not sure if you need a stream or not but feel free to comment:
private void Button_Click(object sender, RoutedEventArgs e)
{
ObservableCollection<string> list = new ObservableCollection<string>();
list.Add("Hallo");
list.Add("Welt");
Task t = Store(list);
}
public static async Task Store(ObservableCollection<string> list)
{
StorageFile file = await GetStorageFileFromApplicationUriAsync();
if (file == null)
{
file = await GetStorageFileFromFileAsync();
}
if (file != null)
{
await file.DeleteAsync();
await CreateFileInInstallationLocation(list);
}
}
private static async Task<StorageFile> GetStorageFileFromFileAsync()
{
StorageFile file = null;
if (file == null)
{
try
{
StorageFolder folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
file = await folder.GetFileAsync("ListCollection.json");
}
catch
{ }
}
return file;
}
private static async Task<StorageFile> GetStorageFileFromApplicationUriAsync()
{
StorageFile file = null;
try
{
Uri path = new Uri("ms-appx:///ListCollection.json");
file = await StorageFile.GetFileFromApplicationUriAsync(path);
}
catch
{ }
return file;
}
private static async Task CreateFileInInstallationLocation(ObservableCollection<string> list)
{
var pkg = Windows.ApplicationModel.Package.Current;
var installedLocationFolder = pkg.InstalledLocation;
try
{
var file = await installedLocationFolder.CreateFileAsync("ListCollection.json", Windows.Storage.CreationCollisionOption.GenerateUniqueName);
var filePath = file.Path;
DataContractJsonSerializer serialize = new DataContractJsonSerializer(typeof(ObservableCollection<String>));
using (Stream stream = await file.OpenStreamForWriteAsync())
{
serialize.WriteObject(stream, list);
stream.Flush();
}
}
catch (Exception ex)
{
var msg = ex.Message;
}
}
What this basically does is:
Find the file
Delete the file
Create a new file
Write your JSON to the file
I am really not an expert on this matter and it even to me seems pretty hacky but it apparently does the job.
If you can avoid writing to the install directory do it and use the method Frank J proposed
I am working on a class that creates or opens an xml file:
namespace QTabs
{
public class DataLayer
{
XmlDocument XMLDocObject = new XmlDocument();
StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
StorageFile storageFile;
string xmlFile = "DataStore.xml";
public DataLayer()
{
loadXML();
}
public async void loadXML()
{
//if XML doc doesnt exist create it
try
{
storageFile = await ApplicationData.Current.LocalFolder.GetFileAsync(xmlFile);
}
catch (FileNotFoundException)
{
storageFile = null;
}
if (storageFile == null)
{
storageFile = await storageFolder.CreateFileAsync(xmlFile);
// Manipulate the xml document.
var root = XMLDocObject.CreateElement("SyncTimes");
XMLDocObject.AppendChild(root);
var childTag1 = XMLDocObject.CreateElement("id");
var childTag2 = XMLDocObject.CreateElement("dateTime");
root.AppendChild(childTag1);
root.AppendChild(childTag2);
await XMLDocObject.SaveToFileAsync(storageFile);
}
else
{
storageFile = await storageFolder.GetFileAsync(xmlFile);
}
}
public async void addSyncTime()
{
XmlElement x1 = XMLDocObject.CreateElement("SyncTime");
XmlElement x11 = XMLDocObject.CreateElement("id");
x11.InnerText = "1";
x1.AppendChild(x11);
XmlElement x12 = XMLDocObject.CreateElement("dateTime");
x12.InnerText = DateTime.Now.ToString();
x1.AppendChild(x12);
await XMLDocObject.SaveToFileAsync(storageFile);
}
}
}
My issue is with the above addSyncTime() method. When it runs it results in the XML file being empty, including removing the elements added on creation.
What am I doing wrong?
Hard to say without a good, minimal, complete code example that reliably reproduces the problem. However, your code appears to have two different problems:
When the XML file is already present, you don't ever bother to actually load it, leaving XMLDocObject referencing an empty document. (Indeed, the storageFile != null case seems completely out of place; not only does it not load the XML from storageFile as I'd expect, it actually re-retrieves the storageFile object by calling GetFileAsync() again).
Your addSyncTime() method creates new elements, but never adds them to the XML document tree.
Given the above, I would expect the program behavior to be:
The first time you run the program, the XML document is created.
Any subsequent time you run the program (unless you delete the XML document), attempts to update the XML document will empty the document.
In neither case would I expect new SyncTime elements to be added. The first time you run the program, you'll get the root SyncTimes element and its initial id and dateTime children, but not any SyncTime elements. After that, the XML document will be emptied, and you'll still not get any new SyncTime elements.
If the above does not address your concern, please provide a good code example as described in the link I provide above.
I can read the text file for first time. when i try to read the same text file next time, it quit the function and return null value.
static string configData = "";
async public void readtextFile(string folder, string file)
{
StorageFolder storageFolder = await Package.Current.InstalledLocation.GetFolderAsync(folder);
StorageFile storageFile = await storageFolder.GetFileAsync(file);
configData = await FileIO.ReadTextAsync(storageFile);
}
Please suggest me, how to resolve this issue..
Thanks
SheikAbdullah
Don't forget that readtextFile is an asynchronous method. When you call it, it actually returns when it reaches the first await, so at this point configData is not set yet. You should return the value from the method, and await the method:
async public Task<string> readtextFile(string folder, string file)
{
StorageFolder storageFolder = await Package.Current.InstalledLocation.GetFolderAsync(folder);
StorageFile storageFile = await storageFolder.GetFileAsync(file);
string configData = await FileIO.ReadTextAsync(storageFile);
return configData;
}
...
string configData = await readTextFile(folder, file);
Even if you want to store configData in a field, you still need to await readtextFile before you read the value.