[Q] NavigationService and form controls - Windows Phone 7 Software Development

I have a main form with a load of controls on it. I have a listbox, and a piece of code that is looking at individual items eg:
Code:
dim listitem as listboxitem = me.listbox.item(0)
when i use the navigationservice.navigate function to navigate to a different page, and then navigate back to the main page i can no longer edit that list box. The code still runs and doesnt error, but the list item is not updating. Its almost like there are two instances of the form open.
Any ideas?
thanks

when im navigating back to the main form i am using another navigationservice.navigate. Im guesing this is creating a new form everytime you use the .navigate as when i use navigationservice.goback from the second form it works fine.
To that end, is there a way you can close a form once you have navigated away from it using .navigate? and can you navigate to an already open form (without creating a new instance) and without using .goforward?
thanks (im using vb silverlight by the way)

adamrob69 said:
... i can no longer edit that list box. The code still runs and doesnt error, but the list item is not updating. Its almost like there are two instances of the form open.
Click to expand...
Click to collapse
Hmm... Could you explain what do you mean? How do you "edit" list box?
Post your code and explain what are you trying to do.
P.S. Have you tried to trace your code with breakpoints on the page constructors? Just try - you will be very surprised

Code:
''MainForm
sub EditListBox()
dim listitem as listboxitem = me.listbox.item(0)
listitem.content = "New List Text"
end sub
sub Navigate()
NavigationService.Navigate(new uri("/Page2.xml",relative))
end sub
Code:
''Form 2
sub NavigateBack()
NavigationService.Navigate(new uri("/MainForm.xml",relative))
end sub
The EditListBox() routine is called every x mins from a system timer. When navigated to form2 then back again the code still runs, i can put a break in and can see it running through the code but the listbox isn't updating. I believe this is because when you use the NavigationService.Navigate function it creates a new instance of the page. On form2 if I use NavigationSevice.GoBack instead of .navigate the main form updates the listbox correctly.
So if that is the case; is there a way you can close a form once you have navigated away from it using NavigationService.navigate? and can you navigate to an already open form (without creating a new instance) and without using .goforward?

I've already gave you a hint (to debug constructors). Yes, if you are using NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative)); or NavigationService.Source = new Uri("/MainPage.xaml", UriKind.Relative); it creates a new page.
This implementation have a sense if you start thinking in web-based terms (what is Silverlight built for!)
BTW, I don't understand your requirements. Why do you need this? What's wrong with GoBack() or GoForward()? Also, have you tried other WP7 layouts (Panorama etc.)?
Try to follow the MS "Metro UI" recommendations and many questions will disappear shortly...

GoFoward won't work:
http://msdn.microsoft.com/en-us/lib...ation.navigationservice.goforward(VS.92).aspx
It seems like your problem isn't navigation, (because you should be using GoBack) but that the previous page that you GoBack to isn't how you wanted it.
If this is the case, you should add some sort of way to tell an event occurred. For example, if you did (note this is really rough)
Page2.xaml.cs
{
...
public static bool VisitedPage = false;
...
}
and when you visit the page, simply set it to true.
Then, when you GoBack, in OnNavigatedTo
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (Page2.VisitedPage)
{
//process why you needed to go tot he page
//clear the page for a fresh run
}
}

Have you tried unselecting that listbox item when you goback?
I had this same issue not too long ago where since it was the same instance of the page the listbox item was still selected when I returned and since the event on the listbox is "selectedchanged" it doesnt change when you select the same 1.

Related

[Q] [Resolved] [.Net CF 3.5] How do i create a treeview based file browser

I have a problem with a project i'm working on and that is:
How do i create a TreeView based file browser that can export a selected path and filename to a textbox and a Process.Start call at the same time. That's it in a nut shell. The main part if the tree view bit but i haven't figured out how to do variables yet and i'm gonna need one for the second part. I have spent hours googling and i have this question posted on a dedicated VB forum.
I'm using Visual Basic 2008 as the IDE and .Net CF 3.5 as the language (obviously)
If anyone has any ideas on this i'll gladly hear them coz i am really stuck. I found writting code to soft reset a device was easier
TreeNodeCollection tr=treeView1.Nodes;
TreeNode tn;
foreach (string dirs in System.IO.Directory.GetDirectories(System.IO.Directory.GetDirectoryRoot(Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName)))
{
tn = new TreeNode(dirs);
//tr = new TreeNodeCollection();
tr.Add(tn);
}
ergintiravoglu said:
TreeNodeCollection tr=treeView1.Nodes;
TreeNode tn;
foreach (string dirs in System.IO.Directory.GetDirectories(System.IO.Directory.GetDirectoryRoot(Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName)))
{
tn = new TreeNode(dirs);
//tr = new TreeNodeCollection();
tr.Add(tn);
}
Click to expand...
Click to collapse
Is that C# code or VB?
M3PH said:
Is that C# code or VB?
Click to expand...
Click to collapse
C#....VB don't have the curly brackets
So i've come back to this question after a few months avoiding VB. I'm now working on a new product and the lack of an folderbrowserdialog object in .Net CF is killing me.
What i need is this (oh and thanks to everyone that posted above but i can't make that solution work). A way to list all the folders on a device and then select one that can be passed to a variable so it's path can be used elsewhere. Maybe also pass the path to a textbox just so it's clear what you have selected. I've spent 2 days googling this and i did find a few things. Most don't work and the rest are in c# which is not much good. So if anyone wants to help me out i would really appreciate it.
Get your head round this.........
O.K. Here's how it's done, with a crash course in one of the most powerful of programming techniques - Recursion. It can confuse the hell out of rookie programmers, as they just can't get their heads round what's going on. It is dependant on a function's local variables and fortunately, .NET's stack based architecture allows us to use it to the full.
You will need, 1.) a TreeView object - named "treeView1" and 2.), a label named "label1" placed underneath it. The label is only there to prove the point that we can get at the full pathname of the selected directory in the Treeview. In reality it can be dropped, just put your processing code directly in the TreeView's AfterSelect() event.
The Form_Load() event gets the directories in the root directory, by calling GetDirList with an initial directory of "\".
GetDirList() adds the directories to the TreeView then calls GetDirList again on each directory to get any subdirectories, and again on each subdirectory, ad nauseum. Keep going until there are no more directories returned.
When completed TreeView contains a list of every directory/subdirectory on the device.
When you select an item from the TreeView the full pathname is displayed in the label. The image at the bottom shows it running under debug on the WinMo 5.0 emulator. There are several directories you would not normally see on your device.
Good Luck, stephj.
Code:
Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs)
Me.GetDirList("\")
End Sub
Private Sub GetDirList(ByVal PathName As String)
Dim dirs As String
For Each dirs In Directory.GetDirectories(PathName)
Dim tn As New TreeNode(dirs)
Me.treeView1.Nodes.Add(tn)
Me.GetDirList(tn.FullPath)
Next
End Sub
Private Sub treeView1_AfterSelect(ByVal sender As Object, ByVal e As TreeViewEventArgs)
Me.label1.Text = e.Node.FullPath
End Sub
P.S.
You will need the VB equivalent of using System.IO adding to your project.
This stuff has been around since .NET CF 1.1
The original project was written in C#, I used .NET Reflector to translate it into VB from the original. The original C# is included here:-
Code:
using System;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace Test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
GetDirList("\\");
}
private void GetDirList(string PathName)
{
foreach (string dirs in System.IO.Directory.GetDirectories(PathName))
{
TreeNode tn = new TreeNode(dirs);
treeView1.Nodes.Add(tn);
GetDirList(tn.FullPath);
}
}
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
label1.Text = e.Node.FullPath;
}
}
}
cool thanks. I'll have a look at coding this tomorrow (i having some fun time right now).
I did have a look at doing this with a list box yesterday but i was getting errors left, right and centre so i really do appreciate the help.
Just an FYI the VB equivelent of "using" is "imports" otherwise most of the objects are the same but i don't nee to worry about adding it as the program is already interacting with the file system.
Again thanks very much. I really appreciate you taking the time to help me out.
I've just had a look at implementing this but i'm having trouble getting the treeview to populate with the folder list. What am i doing wrong? the object names all match up and i can't see why it's not working. Am i just being plain dense?
What i have Is pretty much what you posted except for a few changes to allow for the fact that the treeview object is in a tabcontrol and i already have a bunch of labels knocking around so the label is called label28 and not label1.
I'm sorry if it appears like i'm not trying or i'm asking you to do all the work but i am genuinely really stuck. I get the recursion principal, That's not an issue but i'm trying to create something from scratch that should really have been included in .net CF and i'm just not that good a programmer yet
Should work..... but without seeing the actual code it's rather hard to remotely debug it.
To prove the point, here's the complete VS2008 VB .NET CF 3.5 project.
In the \bin\release directory is the actual executable. If you have .NET CF 3.5 on your device, drop DirList.exe onto it and run it.
I had a look at the project you posted and just copied the coded over. I did make some tweaks so it only loaded the folder list when the tab the treeview was on was clicked but that didn't work so i repated the code in as is and voila! it works. Now all i need is to create a variable to store the selected path in but i think i can manage that.
Again a huge thanks.
Hierarchical view......
Here's the project to indent, compress, and expand the directory tree structure.
I was just playing around with this and i noticed that when you click on a directory below "\" the path becomes "\\this\path". This is obviously not a valid windows mobile path and it is causing an IOexception and I have no idea how to fix it. Google suggests lots of c# pages that say to use a regular expression to strip out the illegal characters but the example i found was for the entire path and it seemed to check each character against a variable of illegal values. I'm sure if that would work for me. Heres the link.
Let me know what you think.
I have no idea where the \\this is coming from, I can't replicate it.
To filter out the extra leading slash use this:-
Code:
Private Sub TreeView1_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterSelect
If TreeView1.SelectedNode.FullPath.Length() = 1 Then
Label1.Text = TreeView1.SelectedNode.FullPath
Else
Label1.Text = TreeView1.SelectedNode.FullPath.Substring(1)
End If
Interesting new problem has cropped up with this code. It doesn't seem to work on rhodiums. It works fine in the emulator, my HD2 and all of CajunFlavouredBob's devices but i have a user that has a rhodium that get the error posted here. I can't replicte it and i don't have a rhodium to test it with. Any ideas?
Hmmmmm another tricky one. Without seeing the device actually throw the error, it can be a bit difficult.
Does this machine actually report the storage card as "\Storage Card"? Some machines don't. In which case you may have to use some storage card enumeration trick to get hold of the real name it uses. This may not apply in this case.
Also, to make things trickier still, the stack dump shows 'GetInternalDirectoryNames()' as the function throwing the error first. This is a level below your call of GetDirectories(), and is being used by the OS to actually go get the info. You may have to create a test version of EXCT2 full of Try...Catch programming blocks, to try to get to the real point where the error is being thrown.
well this turned out to be a memory related issue. So instead of using the folder browser we now use the stock winmo savedialog. because it uses less memory and allows us access to the locations we need.
Thanks for helping though steph.

CheckBox state presrving/restoring

Hi there,
Does anyone out there how to preserve/restore the transient state of a CheckBox and/or Radio button?
So far, I'm using the following code, working for textbox
Code:
Public Sub PreserveState_TextBox(ByVal TB As TextBox)
Dim buffer As String = String.Empty
If True = PhoneApplicationService.Current.State.ContainsKey(TB.Name) Then
buffer = TryCast(PhoneApplicationService.Current.State(TB.Name), String)
If Not String.IsNullOrEmpty(buffer) Then
TB.Text = buffer
End If
End If
End Sub
Public Sub RestoreState_TextBox(ByVal TB As TextBox)
If True = PhoneApplicationService.Current.State.ContainsKey(TB.Name) Then
PhoneApplicationService.Current.State.Remove(TB.Name)
End If
PhoneApplicationService.Current.State.Add(TB.Name, TB.Text)
End Sub
it possible to modify the above code to work for Checkbox and/or Radiobutton?
If not, any ideas?
So far, I've been trying the sample "Tombstoning" sample code from Microsoft without any luck...
Thanks in advance!
Hi,
I'm not a VB developer, but storing the state of a checkbox is not much different from storing any other primitive type. What you could do is have a bool variable "isCbChecked" and store that bool state in your PhoneApplicationService.State.
Code:
PhoneApplicationService.Current.State.Add("isCbChecked", myCheckbox.IsChecked)
Then, when you're restoring your app, simply do
Code:
myCheckbox.IsChecked = (bool)PhoneApplicationService.Current.State.ContainsKey("isCbChecked");
keyboardP said:
Hi,
I'm not a VB developer, but storing the state of a checkbox is not much different from storing any other primitive type. What you could do is have a bool variable "isCbChecked" and store that bool state in your PhoneApplicationService.State.
Code:
PhoneApplicationService.Current.State.Add("isCbChecked", myCheckbox.IsChecked)
Then, when you're restoring your app, simply do
Code:
myCheckbox.IsChecked = (bool)PhoneApplicationService.Current.State.ContainsKey("isCbChecked");
Click to expand...
Click to collapse
Thanks a lot for your fast reply.
Can I ask for additional help on how to make your statements into generic procedures, at least to take them to something similar to what I posted?
Don't care if it's in C#
Thanks in advance!
GFR_2009 said:
Thanks a lot for your fast reply.
Can I ask for additional help on how to make your statements into generic procedures, at least to take them to something similar to what I posted?
Don't care if it's in C#
Thanks in advance!
Click to expand...
Click to collapse
Off the top of my head, something like this should work (C# code).
Code:
public static T RestoreState<T>(string key)
{
if (PhoneApplicationService.Current.State.ContainsKey(key))
{
return (T)PhoneApplicationService.Current.State[key];
}
return null;
}
'T' is the type that will be used. In C# 'T' is a special character denoting the generic type, not something I just used
So in the code above, the return type is 'T' and when using RestoreState, it will be 'RestoreState<Textbox>("TB.Name");'. The value of 'TB.Name' will be searched within the dictionary and, if it's found, it will cast that object as 'T' (Textbox) and return it, otherwise it will return null.
Hi,
So far, I did the following and while no error is raised, nothing happens...
Code:
Public Function Backup(ByVal token As String, ByVal value As Object) As Boolean
If Nothing Is value Then
Return False
End If
Dim store = PhoneApplicationService.Current.State
If store.ContainsKey(token) Then
store(token) = value
Else
store.Add(token, value)
End If
Return True
End Function
Public Function Restore(Of T)(ByVal token As String) As T
Dim store = PhoneApplicationService.Current.State
If Not store.ContainsKey(token) Then
Return Nothing
End If
Return CType(store(token), T)
End Function
I call them as follows
Code:
Backup(Me.CheckBox_1.Name, Me.CheckBox_1)
Restore(Of CheckBox)(Me.CheckBox_1.Name)
Don't where is the error, maybe you could take a look and help me out.
Any help is much appreciated!
Where are you calling the Backup and Restore functions? Since your doing page specific things, you could do it in the OnNavigatedFrom and OnNavigatedTo methods, respectively.
keyboardP said:
Where are you calling the Backup and Restore functions? Since your doing page specific things, you could do it in the OnNavigatedFrom and OnNavigatedTo methods, respectively.
Click to expand...
Click to collapse
Hi,
I'm calling them in the OnNavigatedTo and OnNavigatedFrom methods, as you pointed out
Unfortunately, nothing happens at all!
Thanks!
Hi,
As far as I can tell, there's nothing wrong with your saving/loading code. When you call
"Restore(Of CheckBox)(Me.CheckBox_1.Name)", is that returning a bool? You need to assign that bool to the checkbox:
Code:
myCheckbox.IsChecked = Restore(Of CheckBox)(Me.CheckBox_1.Name);
Also, all variables are reset when the page loads, so make sure you have set "myCheckbox.IsChecked" anywhere else on the page that could be called when the page loads.
Please, check the converted code of the above functions, to C#
Code:
public bool Backup(string token, object value)
{
if (null == value)
{
return false;
}
var store = PhoneApplicationService.Current.State;
if (store.ContainsKey(token))
{
store(token) = value;
}
else
{
store.Add(token, value);
}
return true;
}
public T Restore<T>(string token)
{
var store = PhoneApplicationService.Current.State;
if (! (store.ContainsKey(token)))
{
return default(T);
}
return (T)(store(token));
}
Do you think they are OK?
How should I call them ?
Clearly, the restore does not returns a boolean...
Honestly, I'm lost now!
Hope this helps to find the culprit.
It seems okay to me. You'll have to do some debugging. Set a breakpoint inside the Backup and Restore methods. Step through each line and make sure it's going to the line you expect it to and that the value being set is the correct one.
I haven't seen the tombstoning sample from MSDN, but can you get that to work? If so, is the generic method causing the problem? Or can you not get it to work at all?
Hi,
Sorry for the delay in getting back, but I was trying different codes and at least I found the cause.
Code:
Me.NavigationService.Navigate(New Uri("/PivotPage1.xaml?Name=" & "John", UriKind.Relative))
[B]Me.NavigationService.GoBack[/B]()
Me.NavigationService.Navigate(New Uri("/PivotPage1.xaml", UriKind.Relative))
Everything works fine, and the Checkbox state is saved/restored (in the Pivot Page) if I GO BACK using the GoBack hardware button or Me.NavigationService.GoBack
But, the state's dictionary entry is lost or ignored if I go back with the Navigate service (lines 1 and 3)...
Problem is that I need to get back with the query string...
The query string contains a value taken in the SelectedItem event of PAGE2's ListBox, and automatically once retrieved must go back.
I didn't know until know, that NavigationService.Navigate creates a new page instance or something like that in the backstack...
Any sugestions are welcomed!
Hi,
There are various methods you can use depending on the app's architecture. For example, you could have a 'shared' class that contains a shared field that holds the SelectedItem value. When the user selects the item, set the shared field's value and then when you go back, you can get the value from the shared field.
keyboardP said:
Hi,
There are various methods you can use depending on the app's architecture. For example, you could have a 'shared' class that contains a shared field that holds the SelectedItem value. When the user selects the item, set the shared field's value and then when you go back, you can get the value from the shared field.
Click to expand...
Click to collapse
So, no other way to cope with the navigation service?
It's a strange behaviour for sure...
Will try your ideas.
Thanks a lot for your reply!
GFR_2009 said:
So, no other way to cope with the navigation service?
It's a strange behaviour for sure...
Will try your ideas.
Thanks a lot for your reply!
Click to expand...
Click to collapse
There are other ways. For example, instead of using the PhoneApplicationService to store the tombstoning information, you could put it in a querystring for page 2. Then, in page 2, you could add the information from the previous page to a querystring AND the information of the selected item to the querystring. Navigate to page 1, with the querystring that contains information on what was there before and what the user selected. Tombstoning is there for when the user presses the hardware search button, home button, a phone call arrives etc.. It's not there for the navigation of the app. That's where querystrings, shared variables, binary serialization etc... come into play.
The concept of the navigation service is similar to a website. For example, when you submit something and then go back, it might still be there in the page state. However, if you submit something and then reload the previous page by typing it in the address bar, it becomes a completely new page as no state is stored.
keyboardP said:
There are other ways. For example, instead of using the PhoneApplicationService to store the tombstoning information, you could put it in a querystring for page 2. Then, in page 2, you could add the information from the previous page to a querystring AND the information of the selected item to the querystring. Navigate to page 1, with the querystring that contains information on what was there before and what the user selected. Tombstoning is there for when the user presses the hardware search button, home button, a phone call arrives etc.. It's not there for the navigation of the app. That's where querystrings, shared variables, binary serialization etc... come into play.
The concept of the navigation service is similar to a website. For example, when you submit something and then go back, it might still be there in the page state. However, if you submit something and then reload the previous page by typing it in the address bar, it becomes a completely new page as no state is stored.
Click to expand...
Click to collapse
Hi,
Will try your suggested approach, and thanks a lot for the last explanation on how the darn thing works.
Thanks again!
GFR_2009 said:
Hi,
Will try your suggested approach, and thanks a lot for the last explanation on how the darn thing works.
Thanks again!
Click to expand...
Click to collapse
You're welcome . It's one of those things that take a bit of time to understand, but starts to make sense. You might be interested in a free WP7 development ebook by Charles Petzold.
keyboardP said:
You're welcome . It's one of those things that take a bit of time to understand, but starts to make sense. You might be interested in a free WP7 development ebook by Charles Petzold.
Click to expand...
Click to collapse
I already have the book, but will need a deeper reading
So far, I've been testing your idea of using global classes and works ok.
Thanks a lot for being so cooperative, it's much appreciated!
GFR_2009 said:
I already have the book, but will need a deeper reading
So far, I've been testing your idea of using global classes and works ok.
Thanks a lot for being so cooperative, it's much appreciated!
Click to expand...
Click to collapse
No worries! If programming was super easy everyone would be doing it
keyboardP said:
No worries! If programming was super easy everyone would be doing it
Click to expand...
Click to collapse
Never said better!

[Q] visual studio 2010 code help

been trying to figger out how to write this code for the better part of a day and just cant figger it out. hopefuly someone here can help.
its nothing complex by far, just my lack of knowledge lol.
so,
from the MainPage.xaml, i have a button that i want to link to "item2" on PanoramaPage1.xaml.
i know that this:
NavigationService.Navigate(new Uri("/PanoramaPage1.xaml", UriKind.Relative));
will get me to the Panorama page, but is there a way so ig goes right to item2?
ive tried code like:
NavigationService.Navigate(new Uri("/PanoramaPage1.xaml(item2.SelectedIndex)", UriKind.Relative));
NavigationService.Navigate(new Uri("/PanoramaPage1.xaml(item2)", UriKind.Relative));
NavigationService.Navigate(new Uri("/PanoramaPage1.xaml/item2", UriKind.Relative));
Etc...
but nothing is working for me.
thanx for any help.
poy
Create a property holding the pivotpage you'd like to go to, perhaps _selectedPivotPage. Then set this, to whatever number you need, before calling Navigate() and add something like this.PivotControl.SelectedIndex = _selectedPivotPage to Page_Loaded() in PivotPage1.xaml.cs (or whatever page you're calling).
i really didnt understand much of what you just said... lol
is there anyway you could give me an example?
I've made a quick project which shows this:
http://dl.dropbox.com/u/129101/Panorama.zip
The idea is this:
In the PanoramaPage1's xaml, you add a name for the panorama so you can refer to it in code.
In the PanoramaPage1's xaml.cs, you override the OnNavigatedTo function, which is called when the page is about to be displayed:
// <summary>
/// Overrides PhoneApplicationPage's OnNavigatedTo function, which is called when the page is about to be displayed.
/// </summary>
/// <param name="e"></param>
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
//item2 is the second item, but 0 indexed.
myPanorama.DefaultItem = myPanorama.Items[1];
base.OnNavigatedTo(e);
}
Edit:
This may not be what you're asking. If you're trying to figure out how to send a value which affects the next page (for example change the title of the next page, pass an object, etc), you probably want this example instead
http://dl.dropbox.com/u/129101/Panorama_querystring.zip
williammel said:
Edit:
This may not be what you're asking. If you're trying to figure out how to send a value which affects the next page (for example change the title of the next page, pass an object, etc), you probably want this example instead
http://dl.dropbox.com/u/129101/Panorama_querystring.zip
Click to expand...
Click to collapse
This is exactly what i needed. Thank you sooo much!
poy
No problem. If you're planning on passing complex objects (or any really) you can store them in app.xaml.cs and cut down on the typing, and the time it takes to use the object (since it doesn't have to generate a dictionary you have to query)
Something like this:
Public static string navigationParam;
Or
Public static object navigationobj;
And in any file:
App.navigationparam = "item2";
or
App.navigationobj = (object)myclassvariable;
And just do the opposite to get the item back.

Hack to change default browser

Hello,
I recently bought and installed surfcube (which is pretty cool) but whenever i click on any link outside the browser (ex: twitter/ facebook), it automatically opens an IE window. Any hack out there to get that to go to a different browser, such as surfcube?
This may be based on the default handler for the http: URI format. If anybody finds a way to change this (either the URI handlers, file extension handlers, or just default browser) we would all love to know. I don't think anybody has pulled this off yet, though.
GoodDayToDie said:
This may be based on the default handler for the http: URI format. If anybody finds a way to change this (either the URI handlers, file extension handlers, or just default browser) we would all love to know. I don't think anybody has pulled this off yet, though.
Click to expand...
Click to collapse
And almost more importantly, SurfCube doesn't have the code to read a URL from a command line (or whatever method is used), so the best it would do is just open the app without the specified URL.
davux said:
And almost more importantly, SurfCube doesn't have the code to read a URL from a command line (or whatever method is used), so the best it would do is just open the app without the specified URL.
Click to expand...
Click to collapse
Hi,
I am the developer of SurfCube - if somebody can figure out how to open it as the default browser, we will work hard on making it actually open the URL if it gets passed to us.
That would be pretty cool. I would suspect that there is a registry key for the default handling of URL's. Passing that URL to the third party browserr would most likely need command line and lower file system access.
Sent from my Samsung Focus
HKEY_CLASSES_ROOT is present on WP7, although it works a little differently than on desktop Windows. One thing worth noting is that built-in software, such as IE, is invoked differently from installable apps. Built-in software is compiled to actual EXEs, which of course have a standard way to be passed parameters. WP7 apps are DLLs, invoked by a hosting EXE. Also, the way apps are specified is a bit weird; it's by GUID instead of by path.
There is one installable app which is registered as the handler for a file extension (Adobe Reader for PDF). By picking apart its registry entries, I have at least a partial view of how it works.
HKCR\.pdf:
Default = PDFFile
Content Type = application/pdf
HKCR\PDFFile
AppID = "BC4F319A-9A9A-DF11-A490-00237DE2DB9E"
Application Task = "app://BC4F319A-9A9A-DF11-A490-00237DE2DB9E/_default?"
EditFlags = d:0x00010000
HKCR\PDFFile\shell\open\command
Default = "app://5B04B775-356B-4AA0-AAF8-6491FFEA5665/_default?type=PDFFile&file=%s"
There are some interesting hings here. First of all, the BC4F GUID is the one for the Adobe Reader app. Therefore, AppID is the GUID for an installed app that handles a file or protocol association.
Second of all, the shell\open\command\Default value is present for every openable type, but the GUIDs it contains are *not* in the Applications list (note the difference between it and the AppID value). This appears to be how the OS specifies native applications.
Third, it *is* possible to pass parameters to installable apps. See the %s on the end of the value? That gets replaced by the filename, I suspect. Anybody want do pull apart the Adobe Reader or YouTube apps (the only ones with AppID values) and see how they do it?
Fourth, I'm pretty sure we can use this to add our own associations even if we can't get it to open files in them. I'm not sure how easy it will be, but it should be possible.
For those interested in browsers:
HKCR\http
Default = "HyperText Transfer Protocol"
Source Filter = "{97e7c245-4d6f-483b-a772-de22b15fa999}"
URL Protocol = ""
HKCR\http\Extensions
.3g2 = "{97e7c245-4d6f-483b-a772-de22b15fa999}"
.3gp = "{97e7c245-4d6f-483b-a772-de22b15fa999}"
.aif = "{e436ebb6-524f-11ce-9f53-0020af0ba770}"
... and 20-odd more like this
HKCR\http\Shell\Open\Command
Default = "app://5B04B775-356B-4AA0-AAF8-6491FFEA5665/_default?StartURL=%s"
HKCR\PROTOCOLS\Handler\about
CLSID = "{3050F406-98B5-11CF-BB82-00AA00BDCE0B}"
HKCR\PROTOCOLS\Handler\javascript
CLSID = "{3050F3B2-98B5-11CF-BB82-00AA00BDCE0B}"
HKCR\PROTOCOLS\Handler\mailto
CLSID = "{3050f3DA-98B5-11CF-BB82-00AA00BDCE0B}"
HKCR\PROTOCOLS\Handler\res
CLSID = "{3050F3BC-98B5-11CF-BB82-00AA00BDCE0B}"
... note that these GUIDs are very similar but not the same.
HKCR\.html
Default = "htmlfile"
Content Type = "text/html"
HKCR\htmlfile
Default = "HTML Document"
EditFlags = d:0x00010000
HKCR\htmlfile\CLSID
Default = "{25336920-03F9-11cF-8FD0-00AA00686F13}"
HKCR\htmlfile\Shell\Open\Command
Default = "app://FB04B775-356B-4AA0-AAF8-6491FFEA5660/_default?StartURL=file://%s
HKCR\MIME\Database\Content Type\text/html
CLSID = "{25336920-03F9-11cf-8FD0-00AA00686F13}"
Encoding = 08-00-00-00 (binary)
Extension = ".htm"
I'm omitting a few fairly irrelevant keys, like DefaultIcon. This FB04B775 app is interesting - it seems to serve as a launcher, although that's just a guess for now. In any case, it accepts parameters like StartURL, Type, and File (with the last two coming together) and file substitution (the %s that stands in for the URL or file).
Anybody want to have a go at detangling this?
Also, Good News Everyone: it *is* possible to add associations between unknown extensions and known files, at least. I just added HKCR\.log as a clone of HKCR\.txt (Default = "txtfile"; Content Type = "text/plain") and opening a .LOG file in Outlook now opens the file in Work (it used to trigger a MessageBox saying file type was not known). So cool!
Looks like you can override OnNavigatedTo (from PhoneApplicationBase class) and use NavigationContext.QueryString() to get the required information.
If you use something like
Default = "app://5B04B775-356B-4AA0-AAF8-6491FFEA5665/_default?type=PDFFile&file=%s"
you could use
var params = NavigationContext().QueryString();
if (params.ContainsKey("file"))
{
// code here
}
so any param of the caller url will be part of the query string dictionary.
Hope this helps.
P.S.: Office does it in a more elegant way , They use only one param "CmdLine" and can use the normal cmd line argument parsing on this param, e.g. ...........?CmdLine=-opendoc %s
kuerbis2 said:
Looks like you can override OnNavigatedTo (from PhoneApplicationBase class) and use NavigationContext.QueryString() to get the required information.
...
P.S.: Office does it in a more elegant way , They use only one param "CmdLine" and can use the normal cmd line argument parsing on this param, e.g. ...........?CmdLine=-opendoc %s
Click to expand...
Click to collapse
Yes, this is pretty much what I wanted to go with. The question now is how to get SurfCube to open if you click on a link in en email or twitter or the poeple hub.
I can only imagine one solution (but my imagination is limited <g>): Create two apps.
1.) SurfCube prepared for parameter passing
2.) HomeBrew App which replaces HKCR\http\Shell\Open\Command
-t
kuerbis2 said:
I can only imagine one solution (but my imagination is limited <g>): Create two apps.
1.) SurfCube prepared for parameter passing
2.) HomeBrew App which replaces HKCR\http\Shell\Open\Command
-t
Click to expand...
Click to collapse
Yes, this is exactly what I am thinking about. But I need help with the second one from this group. Also, is there any way to do the registry edits on the emulator? I would prefer to play with that until things get fairly stable.
After digging a bit deeper, it looks like you are out of luck. I don't know why but the AppID of MobileIE is hardcoded in the WebBrowserTask (reference assemblies and Samsung Omnia 7 GAC assembly):
ChooserHelper.LaunchSession("app://5B04B775-356B-4AA0-AAF8-6491FFEA5660/_default?StartURL=" + this.URL);
So, even if you manage to change the html handler, you won't get the calls from the correspondig task.
Long time since I've seen something hardcoded like this on a windows platform...
I can't confirm this now, but I think 5b04b is actually the application host process. In other words, it's the thing that makes the navigation buttons work, and which runs the installable app DLLs. The StartURL parameter may just mean "look up things defined as a URL Protocol (HTTP is one such thing) and launch the corresponding app." The Filter value may be relevant here, perhaps even as the actual app id for IE. In any case, I get the feeling that the reason it's hard-coded is because it's the launcher app, and StartUrl is just how you tell it to invoke the web browser.
However, the hardcoded GUID and the ones in htmlfile, http and related keys is different from for example the one used in PDFFile.
Crap, you're right. I wasn't paying enough attention to the last couple digits. It doesn't help that searching registry data (as opposed to keys and value names) doesn't seem to work. I'm tempted to say that some experimentation is in order, although I'd prefer to know what I'm messing with.

[Q] How to implement Transparent Labels and other controls [vb.net]

I've been banging my head against this one all morning and now i have a head ache so i decided to stick it out to you lot.
I want to make all my user controls (labels, checkbox's etc) transparent - well the text at least. I found this thread on MSDN but i'll be honest and say i'm not entirely sure what i'm supposed to do with it.
Thanks for your thoughts.
Works a treat. Lifted the code from the site and dropped it straight into the form class.
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.WindowsCE.Forms;
namespace TestDevApp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
forum.xda-developers.com/search.php?searchid=90851847
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
DrawLabel(label1,e.Graphics);
DrawLabel(label2, e.Graphics);
DrawLabel(label3, e.Graphics);
DrawLabel(label4, e.Graphics);
}
private void DrawLabel(Label label, Graphics gfx)
{
if (label.TextAlign == ContentAlignment.TopLeft)
{
gfx.DrawString(label.Text, label.Font, new SolidBrush(label.ForeColor), label.Bounds);
}
else if (label.TextAlign == ContentAlignment.TopCenter)
{
SizeF size = gfx.MeasureString(label.Text, label.Font);
float left = ((float)this.Width + label.Left) / 2 - size.Width / 2;
RectangleF rect = new RectangleF(left, (float)label.Top, size.Width, label.Height);
gfx.DrawString(label.Text, label.Font, new SolidBrush(label.ForeColor), rect);
}
else //is aligned at TopRight
{
SizeF size = gfx.MeasureString(label.Text, label.Font);
float left = (float)label.Width - size.Width + label.Left;
RectangleF rect = new RectangleF(left, (float)label.Top, size.Width, label.Height);
gfx.DrawString(label.Text, label.Font, new SolidBrush(label.ForeColor), rect);
}
}
}
}
Devtrans is the view in VS
Transparent is the actual running code.
Cool thanks.
I did try using DrawString but the drawn text doesn't scroll with the form when you... well.... scroll the form.
I'm gonna have the afternoon off but i will check it out properly later. Would this also work for check boxes? If so what are the changes that would need to be made?
Checkboxes might be a different matter. The above method does not work, it only deals with the text caption. There is is an article on The Code Project at
http://www.codeproject.com/KB/dotnet/TransparentControl.aspx
It appears like they have almost created a control from scratch. You may have to take control/override that much of the object, to get it to work, that you have almost created a new control.
stephj said:
Checkboxes might be a different matter. The above method does not work, it only deals with the text caption. There is is an article on The Code Project at
http://www.codeproject.com/KB/dotnet/TransparentControl.aspx
It appears like they have almost created a control from scratch. You may have to take control/override that much of the object, to get it to work, that you have almost created a new control.
Click to expand...
Click to collapse
I did see that page but i couldn't figure out how the hell to use it
Ok, so now you have found one of the BIGGEST challenges to WM development.
I spent 4+ months trying to get the same thing you are looking for (well, what I assume you are looking for), that is: A transparent label that you can use your finger to scroll.
If that is what you are looking for, I can tell you right now that you need to either look into custom controls that already do this or decide how much time you are willing to invest into something as simple as that.
Here is the basic components that you will need to code to get DrawString to properly scroll with your finger:
You will need to code up some kind of container or panel that holds the current virtual x,y coordinates.
You will need to code up some kind of custom control that can be added to the previously made container
Create logic in the container to take the current virtual x,y coords and determine which custom controls are visible and should be drawn on the screen, pass them their offset coords, and draw the control
Override the OnMouse*ACTION* events on the container to manipulate the virtual x,y coords and then refresh the screen
You also will need to know about double buffering so you don't get any flickering.
It's a very very hard thing to do on WinMo, something that other platforms take for granted. This is one of the reasons that some custom WinMo programs have UIs that are either really terrible, or take tons of resources.
If you want to give it a go (and I would highly recommend doing it, I can't tell you how much I learned about software development by creating my own custom controls) I can help point you in the right directions. Feel free to take a look at the code I've written for my Facebook app (specifically the XFControls and SenseUI projects). I'm not on XDA as often as I'd like, but send me a PM with your questions and I'll respond when I log in.
Good Luck!

Categories

Resources