[REQ] Need some info on MDIs in Smart device applications using C#.net - Windows Mobile Software Development

Hi all guys
i am new to C# and .net stuff as i was working with C++ for many years
i want to know that is it possibhle that i can have an MDI Child Form on my main Form and want it to return me some data
like for example i have my main Form has a "settings" button
when i click on "settings" button it should show a small MDI child form which has all the settings and return some data (i'll take care of data but i dont know how to return through a form)
thnx in advance

Well...as far as 'returning' data from the Form, you can't do that as a "return" call because Forms are objects, so the constructor cannot have a return type, however you can have a method that will set a variable in another class (that is public) to the data you want to return ... You can call this method when the form is closing.
I am not entirely sure if you can achieve the 'small form INSIDE another form' without creating your own control. I am not sure how practical/possible this would be, but you can try 1 of the following: extend the Control class (to make a control) or override the OnPaint of a new Form. This way you can define where stuff goes, and what gets drawn onto the screen.

I have used this piece of code in the past, which worked great.
in my example frmA was an MDIchildform of the main (MDIparent)
frmA()
{
public int a=0;
private btn_click(blabla)
{
frmOptions options = new frmOptions(this);
dialog.ShowDialog();
if(dialog.DialogResult == DialogResult.Yes)
{
dosomethingwith(a);
}
else
{
donothingwith(a);
}
}
}
public partial class frmOptions : Form
{
frmA callingform = null;
public frmOptions(frmA x)
{
callingform = x;
}
private void dosomething()
{
callingform.a = value;
}
private void btnSaveSettings_click()
{
this.DialogResult = DialogResult.Yes;
}
private void btnCancelSettings_click()
{
this.DialogResult = DialogResult.No;
}
}
good luck

Related

[Q] Standard and Professional

Newbie here. Maybe someone can give me some direction. I am writing an app for both standard and professional. I have 2 projects in my solution. One is for standard the othe is for professional. I am not sure if this is the right way or not but what I want to do is when the app opens it checks to see what platform is running and then runs the correct project. Any help would be greatly appreciated.
It is possible to create a single project that is capable of running on both platforms but there is quite a bit of groundwork you will have to do first.
Firstly, the main differences.
Standard : No touch screen i.e. No Mouse events. All user input is via the keyboard, buttons, D-PAD and ENTER. No Open/Save dialogboxes, you have to present the files to the user yourself. Message dialogs appear full screen.
Professional : None of the above limitations.
The are a few pointers here:
http://msdn.microsoft.com/en-us/library/bb985500.aspx
The following code will detect the platform and set the variable 'SmartPhone' to 1 (true) if the version is 'Standard'
Code:
#define MAX_LOADSTRING 100
int SmartPhone;
TCHAR szReturn[MAX_LOADSTRING];
SystemParametersInfo(SPI_GETPLATFORMTYPE,MAX_LOADSTRING,szReturn,false);
SmartPhone=wcscmp(TEXT("SmartPhone"),szReturn)^1;
Your processing code may have code such as:
Code:
if(SmartPhone)
{
........ Standard Stuff.......
}
else
{
......... Professional Stuff........
}
Note also that code dealing with a WM_LBUTTONDOWN message will never be executed on a smartphone, as WinMo Standard never generates this message.
It may seem a pain, but you only have one executable to deliver for both platforms.
As an example, here's one I prepared earlier.
http://forum.xda-developers.com/showthread.php?t=509413
more info
I am coding with VB. What I was thinking was creating a class project and making that the startup project. Within the class the VB would check the platform and then run the correct project.
Should work:
To get the Platform type in .NET CF have a look at:
http://msdn.microsoft.com/en-us/library/ms229660(VS.90).aspx
It's also listed in the VS Help.
I am using VS2008 TS and cf3.5. I have tried several methods and still can't get any to work. I must be missing a reference or something. Here is some code I can't get to work.
If SystemSettings.Platform = WinCEPlatform.PocketPC Then
txtDeviceType.Text = "Windows Mobile Professional"
ElseIf SystemSettings.Platform = WinCEPlatform.Smartphone Then
txtDeviceType.Text = "Windows Mobile Standard"
Else
txtDeviceType.Text = "Not Windows Mobile"
End If
Also tried this.
Public Enumeration WinCEPlatform
Dim instance As WinCEPlatform
I also tried getversionex but couldn't get it to work either.
I only code .NET in C# but there is virtually no difference.
Try this: You will have to add the reference to Microsoft.WindowsCE.Forms;
Right click on References in the Solution Explorer, click on Add Reference, in the .NET Tab, pick it out of the list.
Code:
using System;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.WindowsCE.Forms;
namespace Test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
WinCEPlatform Platform = new WinCEPlatform();
Platform = SystemSettings.Platform;
label1.Text = Platform.ToString();
}
}
}
Works a treat!
Let's let Red Gate's Reflector translate the IL into VB.
It also reveals that the compiler rips outs the middle variables and goes straight for :
Code:
Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs)
Me.label1.Text = SystemSettings.Platform.ToString
End Sub
I am getting an error on this InitializeComponent. Another question. Can I add a class project and use this code to point to the correct project?
Drop the InitialiseComponent function, that is only used used in C#
In VB in Form1 the only code you need is
Code:
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Label1.Text = Microsoft.WindowsCE.Forms.SystemSettings.Platform.ToString
End Sub
End Class
This code works and puts "YES" in the box if run on a PPC
Code:
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
If Microsoft.WindowsCE.Forms.SystemSettings.Platform = Microsoft.WindowsCE.Forms.WinCEPlatform.PocketPC Then
Label1.Text = "YES"
End If
End Sub
End Class
Ok. I got it to work with the following code. But I have another problem. My app is a very simple app. I want it to work on PPC2003 and smartphones. I have 2 different forms for standard and professional. Now the problem is that if I use .net compact framework 3.5 then the device has to have that installed. So if I want to the app to work on older devices it won't work without the .net compact framework. If I use .net compact framework 2.0 then I lose the ability to use the code to determine if its standard or professional. I was hoping there was a way to include the 3.5 CF into my app cab but I haven't seen it. I am currently using VS2008 whcih only allows you 2.0 CF and 3.5 CF. I was thinking about using VS2005 and use 1.0 CF so it would work on all Windows mobile devices. But then I would again lose the ability to use the code. Any ideas would be appreciated.
Shared Sub Main()
Dim Platform As New WinCEPlatform()
Platform = SystemSettings.Platform
If Platform = "1" Then
Application.Run(
New Pro())
ElseIf Platform = "2" Then
Application.Run(
New Standard())
End If
End Sub
Using VS2005 I started a new project and selected SmartDevice 1.0. Now I have some issues.
1. Trying to determine either standard or professional. I am trying to use the Pinvoke to do this. No luck so far. I get an error on ByVal nFolder As ceFolders.
2. The code I was using to play a .wav file no longer works.
Dim myplayer As New System.Media.SoundPlayer(New IO.MemoryStream(My.Resources.Dice))
myplayer.Play()
3. I had resource files for images and a wav file so my code to use these no longer work.
Me.PictureBox1.Image = My.Resources.red_die_1_th
1. I'll have a look at it. Watch this space.
2. The SoundPlayer object is only available from .net CF 3.5 onwards. To play sounds you my have to PInvoke PlaySound()
http://msdn.microsoft.com/en-us/library/ms229685(v=VS.80).aspx
3. Should work, but maybe there's a difference in the frameworks. Microsoft's catch-all is that not all methods, properties etc. are supported in all .NET or .NET CF. versions. You may end up doing it in two stages, create a bitmap image from the resource, then pass that to the picturebox.
The answer to 1 is below. This works in C# under VS2003 .NET CF 1.0 but it is only in C#, I do not have VB installed on this machine. You will have to reverse engineer it into VB yourself, not too difficult. The important code is the DLLImport definition, the SPI_GETPLATFORMTYPE definition, and the call of the function in Form1_Load().
On program start "PocketPC" appears in the label on screen.
Code:
using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;
namespace PInvTest
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Label label1;
private System.Windows.Forms.MainMenu mainMenu1;
[DllImport("coredll.dll", EntryPoint="SystemParametersInfo", SetLastError=true)]
private static extern int SystemParametersInfo(
int uiAction, int uiParam, string pvParam, int fWinIni);
private const int SPI_GETPLATFORMTYPE = 257;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
base.Dispose( disposing );
}
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
Application.Run(new Form1());
}
private void Form1_Load(object sender, System.EventArgs e)
{
string Platform = new string(' ',20);
SystemParametersInfo(SPI_GETPLATFORMTYPE,Platform.Length,Platform,0);
label1.Text=Platform;
}
}
}

[Q] How to delete/add an item from a ListBox?

Hi there,
I have a ListBox bounded to a query (linq to xml)
Dim CASDAs XDocument = XDocument.Load("./Data/CASD.xml")
Dim CAS_Query As System.Collections.IEnumerable = From query In Cartridge_Doc.Descendants("Cartridges") Order By _
CStr(query.Element("AA")) Descending, CStr(query.Element("AA"))
Select New Cartridge_Data With {.AA1 = CStr(query.Element("AA")), _
.BB1= CStr(query.Element("BB")), _
.CC1 = CStr(query.Element("CC"))}
Me.ListBox_1.ItemsSource = CAS_Query
Now, what I need to do is to select an item and have the option to delete it.
So far, I always got a run-time exception when trying this
Me.ListBox_1.Items.Remove(Me.ListBox_1.SelectedItem)
System.InvalidOperationException was unhandled
Message=Operation not supported on read-only collection.
So far I have tried a lot of options without any luck.
Any help will be greatly appreciated!
Thanks in advance.
Stick your Linq result in an ObservableCollection, bind this to the Listbox and delete the item directly from the underlaying collection.
emigrating said:
Stick your Linq result in an ObservableCollection, bind this to the Listbox and delete the item directly from the underlaying collection.
Click to expand...
Click to collapse
Please, can you poost a little code to do that? I'm fairly new to this collections world.
On the other hand, once the item got deleted, how the Listbox gets refreshed?
Thanks!
You have to set up an NotifyPropertyChanged class to keep the listbox updated with your collection. The default phone list application template that comes with Visual Studio shows you how to do this. I think its's in c# though and it looks like you're coding in VB. I'm sure there's examples in VB you can find on the web with a little searching.
Ren13B said:
You have to set up an NotifyPropertyChanged class to keep the listbox updated with your collection. The default phone list application template that comes with Visual Studio shows you how to do this. I think its's in c# though and it looks like you're coding in VB. I'm sure there's examples in VB you can find on the web with a little searching.
Click to expand...
Click to collapse
My ListBox takes its data from an XML file via query.
Which strategy do you think is the best?
To first delete the Xelement then refresh the ListBox?
Or deleting from the item from the ListBox, then update the XML file?
Sorry but I have all the samples from MS and didn't find any phone list one.
Any code will be greatly appreciated!
Oops. It's called "Windows Phone Databound Application". Attached is a screenshot of the project if it makes it easier for you to find it.
It's hard to post code because I don't know what your xaml looks like and bindings have to be set there for it to work. The best thing you can do is load the above project and play around with it.
You never have to refresh the items in the listbox. A bound listbox updates itself when an item in the collection changes. Change the collection and your listbox will reflect those changes. The NotifyPropertyChanged class is what triggers the listbox to update itself.
I do C#, not VB but the following should give you some idea.
Code:
public class Model : INotifyPropertyChanged
{
public string Title { get; set; }
public string Blurb { get; set; }
public event PropertyChangedEventHandler PropChanged;
public void NotifyPropertyChanged(String _propName)
{
if (null!=PropChanged)
{ PropChanged(this, new PropertyChangedEventArgs(_propName)); }
}
}
The above is your model, create any properties you need there - i.e. one per item of data in your XML file.
Next, you need to create an ObservableCollection somewhere, for the sake of simplicity let's stick it in your MainPage.xaml.cs file for now, so;
Code:
public partial class MainPage : PhoneApplicationPage
{
public ObservableCollection<Model> Items { get; set; }
public MainPage()
{
InitializeComponent();
this.Items = new ObservableCollection<Model>();
MyListBox.ItemsSource = this.Items;
WebClient wc = new WebClient();
wc.OpenReadCompleted += wc_OpenReadCompleted;
wc.OpenReadAsync(new Uri("http://your.server.here/datafile.xml");
}
public void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
using (Stream s = e.Result)
{
XDocument xd = Xdocument.Load(s);
var XMLdata = (from q in doc.Descendants("Item") select new Model()
{
Title = (string)q.Element("Title"),
Blurb = (string)q.Element("Blurb")
}
foreach (Model m in XMLdata)
{
this.Items.Add(m);
}
}
}
public MyListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListBox lb = (ListBox)sender;
if (lb.SelectedIndex == -1)
return;
this.Items.Remove(lb.SelectedItem)
}
}
This will create a collection named Items as well as tell your ListBox (named MyListBox) to get it's data from said collection. Then it will read (asynchroniously) the XML file from the web and copy each item of data into your collection.
When you select an item in your ListBox it will be deleted from the ObservableCollection which in turn will remove it from the view (ListBox). At this stage you want to include code to also remove this from your actual XML file and so on of course. But the idea is that you work on your Collection only and your View will update based on what is changed - automagically.
Please note, the above code may or may not work out of the box. Written directly here on the forums so it hasn't gone thru VS2010's excellent IntelliSense. Also, the above code is in no way the most efficient way of doing certain things, but it gives you an idea as to what code you need to write to handle your scenario.
While I wrote this I see you've got an answer above which directs you to the VS template - use that and everything should become clear. All you have to remember is that perform operations on the Collection - not directly on the ListBox and you'll be fine.
Emigrating and Ren13B,
Thanks to both of you for the help. Very appreciated!
Will take both advices to see what comes up.
Thanks!

Legal Text and Code Sample for WP7 Application Eula

I am learning programming and trying to finish off my first WP7 application.
My day job is a corporate commercial attorney in Montreal, Quebec Canada but I like to experiment with programming as a hobby.
I was surprised that no easy mechanism was provided for an End User Licence Agreement so I drafted one using precedents.
This EULA not only protects your ip but it provides for updates, additional services and, most importantly, limitation of liability and warranty.
I want the user to be presented with the usual "I agree" button when loading the application so I set up a key in the application settings entitled licence with a bool variable that stores false if the user has not accepted the EULA and true if the user has accepted this. I then check this key on app startup to determine the page I present to the user, whether it be the EULA page or the 1st page of the application. Once the user clicks the I agree, the key is set to true and the EULA is not presented again.
On mainpage I use the following code to test if the licence was accepted (it is basic, but works):
public Classes.AppSettings appsettings = new Classes.AppSettings();
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
// Display Message box for licence
if (!appsettings.getsettings("licence"))
{
this.NavigationService.Navigate(new Uri("/EULA.xaml", UriKind.Relative));
}
}
As you can see, if licence is false, there is a navigation to the eula page.
Here is the function I use to store key in the application settings. It works for bool variables and can be re-used.
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.IO.IsolatedStorage;
namespace Car_Mileage_Tracker_2.Classes
{
public class AppSettings
{
// This class is used to store setting in application settings
// SETTINGS
// FIRSTUSE bool TRUE is not first use FALSE is first use
// LICENCE bool TRUE is licence accepted FALSE is licence not accepted
// HELP bool TRUE is help messaged displayed FALSE is help message not displayed
// UNITS bool TRUE is km and FALSE is miles
public AppSettings(){}
public bool getsettings(string key)
{
var store = IsolatedStorageSettings.ApplicationSettings;
bool value = true;
if (store.Contains(key))
{
try
{
store.TryGetValue(key, out value);
return value;
}
catch
{
MessageBox.Show("Could not retrieve setting " + key + " from Application Settings");
return false;
}
}
else { return false; }
}
public void setsettings(string key, bool value)
{
var store = IsolatedStorageSettings.ApplicationSettings;
if (store.Contains(key))
{
try { store[key] = value; }
catch
{
MessageBox.Show("Could not save " + key + " setting in Application Settings");
}
}
else { store.Add(key, value); }
}
}
}
I have attached the EULA xaml page as well as the EULA cs page and a word document containing my sample EULA. To circumvent upload restrictions I have added txt to the xaml and cs files, you simply need to rename them. You will need to fill in the info for your company and edit section 13 to provide for your local court district and state/province/country. Also, I have not yet implemented the code for clicking on the I disagree button. This seems to be a touchy issue in WP7 Silverlight as there is no way to cause an application to terminate except by raising an exception which may be against marketplace rules. I probably will show another page explaining to the user that he/she cannot use the application without agreeing to the EULA but I am not there yet
I feel that this EULA affords me sufficient protection as a developer of an application but make no warranties to this effect and it is always recommended to have it verified by your lawyer.
I hope this may be of use to some of you developing apps.
If you have comments or suggestions, let me know or send me a pm. If you appreciate and use this, then you can, but are not obligated to send me some coffee money or a copy of your app
I will eventually translate the EULA in French, but if would be great if we could get a Spanish, Italian and German version of this.
Have fun.
Message to thread Moderator: If this is not posted in the proper thread/forum, please feel free to move it to the correct one.

[Q] ListBox Binding Error with Observable Collection

Hi all!
Since days I have a problem now. I have an app that manage Entries in a list A. If one of these entries End-Date is today I whant that entry to be shown in a second list B. This is checked when I return from the "addNewItem" Window so I use onNavigatedTo.
Code:
// Static Variables
public static ObservableCollection<Item> lstToday = new ObservableCollection<Item>();
public static ObservableCollection<Item> lstWeek = new ObservableCollection<Item>();
public static ObservableCollection<Item> lstAll = new ObservableCollection<Item>();
// Constructor
public MainPage()
{
InitializeComponent();
MessageBox.Show("Initialize Component");
lbToday.ItemsSource = lstToday;
lbWeek.ItemsSource = lstWeek;
lbAll.ItemsSource = lstAll;
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
DateTime currentDate = DateTime.Now;
foreach (Item item in lstAll)
{
if (item.endDate.ToString("yyyy'-'MM'-'dd").Equals(currentDate.ToString("yyyy'-'MM'-'dd")))
{
lstToday.Add(item);
MessageBox.Show("Item '" + item.name + "' added to Todaylist");
}
}
}
private void appBarNew_Click(object sender, EventArgs e)
{
NavigationService.Navigate(new Uri(string.Format("/EditAddItem.xaml"), UriKind.Relative));
}
After that I get an "System.Diagnostics.Debugger.Break();" error that doesn't occur when I delete "lbToday.ItemsSource = lstToday;" to avoid the ListBox Binding.
With lbAll ist runs without any problems!
Can I bind the Listbox direct to the ObservableCollection in XAML=
I really don't know, whats to do. So do you?
It would make my day!
Thanks!
What is the exception message and stack trace when the exception is thrown? (you can browse the properties of the exception using visual studio).
Your code actually works for me (although I had to make some assumptions about what is in lstAll as you don't mention that, and you may have an error in the DataTemplate for the listbox for binding your Item class)
Things to try:
Have you tried it with non static observable collections?
Use binding assignments in the xaml rather than setting the itemssource directly (e.g. using a viewmodel). Then you can let the phone engine worry about when to do the assigments. If you do that don't forget to set the page's datacontext property.
Try it with simple collections of strings first (rather than binding an 'item' class) so you can check it's working without a datatemplate.
Hope you fix it.
Ian

Advice on strategy

I'm developing a WP7 app, working alongside a Windows (server) application. They are talking with each other using sockets.
As soon as the WP7 app opens, I wish to perform a network scan to find the server application.
I already found out how to get the IP address of the WP7. So let's say I know the server should be somewhere at 192.168.0.*. How do I go about scanning this network?
I tried many things, the last of which is the code below. The problem here is that somehow the TIMEOUT_MILLISECONDS parameter seems to be like playing roulette (tried everything in the range of 100-2000 with different success). In addition, if I sweep the whole subnet like in the code below the phone cannot seem to handle the work. I only get it to work if I set the timeout to 2000 (which is way to long) and by scanning up to 5 IP's in the for-loop, instead of the whole subnet.
Is there anyone that knows a better and much more efficient(!) way to do this?
Code:
string thisIP = "192.168.0.101"; // I normally get this from some other function
string[] arrIP = thisIP.ToString().Split('.');
string IPBase = arrIP[0] + "." + arrIP[1] + "." + arrIP[2] + ".";
//MessageBox.Show(address.ToString());
for (int i = 2; i < 254; i++) {
string IP = IPBase + i;
CheckConnection CheckConn = new CheckConnection();
string resultConnect = CheckConn.Connect(IP, int.Parse(Resource1.port));
if (resultConnect == "Success") {
CheckConn.Send("isAlive");
string result = CheckConn.Receive();
if (result.Contains("yes")) {
// We have found the server
break;
}
}
CheckConn.Close();
}
Code:
public class CheckConnection
{
// Cached Socket object that will be used by each call for the lifetime of this class
Socket _socket = null;
static ManualResetEvent _clientDone = new ManualResetEvent(false);
const int TIMEOUT_MILLISECONDS = 100;
const int MAX_BUFFER_SIZE = 2048;
public string Connect(string hostName, int portNumber) {
string result = string.Empty;
DnsEndPoint hostEntry = new DnsEndPoint(hostName, portNumber);
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
socketEventArg.RemoteEndPoint = hostEntry;
socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e) {
result = e.SocketError.ToString();
_clientDone.Set();
});
_clientDone.Reset();
_socket.ConnectAsync(socketEventArg);
_clientDone.WaitOne(TIMEOUT_MILLISECONDS);
return result;
}
public string Send(string data) {
string response = "Operation Timeout";
if (_socket != null) {
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
socketEventArg.RemoteEndPoint = _socket.RemoteEndPoint;
socketEventArg.UserToken = null;
socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e) {
response = e.SocketError.ToString();
_clientDone.Set();
});
byte[] payload = Encoding.UTF8.GetBytes(data);
socketEventArg.SetBuffer(payload, 0, payload.Length);
_clientDone.Reset();
_socket.SendAsync(socketEventArg);
// Block the UI thread for a maximum of TIMEOUT_MILLISECONDS seconds.
// If no response comes back within this time then proceed
_clientDone.WaitOne(TIMEOUT_MILLISECONDS);
}
else {
response = "Socket is not initialized";
}
return response;
}
public string Receive() {
string response = "Operation Timeout";
if (_socket != null) {
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
socketEventArg.RemoteEndPoint = _socket.RemoteEndPoint;
socketEventArg.SetBuffer(new Byte[MAX_BUFFER_SIZE], 0, MAX_BUFFER_SIZE);
socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e) {
if (e.SocketError == SocketError.Success) {
response = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred);
response = response.Trim('\0');
}
else {
response = e.SocketError.ToString();
}
_clientDone.Set();
});
_clientDone.Reset();
_socket.ReceiveAsync(socketEventArg);
_clientDone.WaitOne(TIMEOUT_MILLISECONDS);
}
else {
response = "Socket is not initialized";
}
return response;
}
public void Close() {
if (_socket != null) {
_socket.Close();
}
}
}
Why you don't know the server IP?
I can't help you with your subnet scanning problem, don't have experience with that corner of WP7 programming.
But I do wonder what kind of arrangement leads to the problem that your app does not know the server address and therefore has to scan for it. Is neither a fixed IP available for your server nor some kind of DNS service up to tell you the current IP?
Even if there are multiple servers running and the phone has the job to somehow decide which one of those is responsible for it, you still could set up some kind of super-server that the phones could ask first which server they should address.
In any way, phones scanning subnets to find servers as some routine app startup action is a bad idea, if you ask me.
Please note that by 'server' I'm just revering to a software that accepts socket connections. This software is installed into a Windows computer that most likely has it's IP from DHCP.
The server software itself could present it's IP address so the end-user can type this address into the client on their WP7. Nice for tech-savvy folks, but that's not how software should be designed in my opinion. People don't need to know what an IP address is and shouldn't be force into typing 'weird numbers'. Properly designed software just have to work instantly and developers (again in my opinion) need to take care of a good design and that includes making things plug-and-play where they can.
Take a look at 'PC Remote' and you will see the kind of easy plug-and-play experience I'm looking for.
Did you check broadcast?
I'm really not network guy, but from Googling I got the impression that people use broadcast instead of IP range scanning for such IP number discovery tasks, and there seems to be a way to do broadcast on WP7 (albeit only using some tricks / hardly documented functionalilty):
E.g. see this thread:
http://stackoverflow.com/questions/8533471/udp-broadcasting-in-windows-phone-7
Which links to this:
http://forums.create.msdn.com/forums/t/88975.aspx
This makes sense to me after reading that broadcast is also the method how a client finds its DHCP server - isn't that the exact same scenario like yours?
Did you already check this way of looking at the problem, or maybe rule it out already for some reason?
It's better if you use a multicast group to send/receive packages. I had way better experience with it than using the Broadcast IP.
You need to join the multicast group with the phone and with the server app. I know there are multicast classes but I found it easier and mor convient to implement it with a socket...
And after you found the server, I'd use a persistent tcp connection which should improve your network performance (udp and wp7 is sometimes really strange...)
Thanks rbrunner7 and chabun for your comments, I appreciate your input!
rbrunner7 said:
Did you already check this way of looking at the problem, or maybe rule it out already for some reason?
Click to expand...
Click to collapse
I did, briefly, but abandoned this path after reading about the physical network equipment (switches etc.) having the need to support broadcasting which might not always be the case.
Anyway, your mentioned post describes 'limited broadcasting', which might be exactly what I should be looking for. Hopefully hardware limitations will not be applicable; I will look into this method further and will let you know how it works out!
roady001 said:
the physical network equipment (switches etc.) having the need to support broadcasting which might not always be the case.
Click to expand...
Click to collapse
I had the same doubts about that as it's also the case for multicasting. Most modern equipement supports it though and you can always provide the possibility to manually enter the server ip if you can't discover one via multicast/broadcast

Categories

Resources