I am using the onNavigate method in windows phone 8.1 and trying to pass a list of navigation objects I have created. When I try and retrieve the list from e.parameters (which seems to work) I cannot iterate through the list and cast them back to the original object types. It works if I send a single object but not a list.
For Example.
From a button_click event on the mainpage I am calling the code below to navigate to page2 and pass a list of objects.
I have a class defined as below.
class NavigationContext
{
public int ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
For testing I create 3 objects and add it to a list as follows
NavigationContext navobj = new NavigationContext(){ID = 77,Name = "DN", Description = "TD1"};
NavigationContext navobj2 = new NavigationContext(){ID = 22,Name = "JN",Description = "JD1"};
NavigationContext navobj3 = new NavigationContext(){ID = 22,Name = "CN",Description = "CN1"};
I then create the list as below
List<NavigationContext> navlist = new List<NavigationContext>(){navobj,navobj2,navobj3};
I then Make the call below
Frame.Navigate(typeof(Page2), navlist);
If I pass one object the code works and compiles and the new page is navigated too sucessfully*
**If I pass a list as above I get the following error on the foreach iterator in the OnNavigatedTo method
**Example code below*
string myfiller = "";
foreach (NavigationContext navobj in e.Parameter)
{
myfiller += navobj.ID.ToString() + " " + navobj.Name + " " + navobj.Description+ "\n";
}
I get the following error:
foreach statement cannot operate on variables of type 'object' because 'object' does not contain a public definition for GetENumerator.
I have tried to find ways to cast the list back to NavigationContext objects but I think I am doing something stupid because I cann0t get it to work.
Any suggestions?
Try this:
List<NavigationContext> navigationObjects = e.Parameter as List<NavigationContext>;
if(null != navigationObjects)
{
foreach (NavigationContext navobj in navigationObjects)
{
myfiller += navobj.ID.ToString() + " " + navobj.Name + " " + navobj.Description+ "\n";
}
}
Note that if the e.Parameter object cannot be interpreted as the correct type (a List<NavigationContext>) then using the as operator will result in a null value that can be tested to prevent further problems when you try to use the elements of the list as NavigationContext objects.
Related
I've done a fair bit of research, but I can't find anyone who has the same problem as me (sadly). I am using LiteDB to create a NoSQL database.
When the program first runs and the database is created, the query in the example below works just fine. When I restart the program, it fails saying that it is null. The weird thing is, if I do a count it returns 8 records. So something exists - why can't I pull it out?
Here is my code:
public class ExternalTools
{
public int Id { get; set; }
public string Name { get; set; }
public string[] Types { get; set; }
}
public void GetAll()
{
var localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
var folderPath = localFolder.Path;
var filePath = Path.Combine(folderPath, #"MyData4.db");
using (var db = new LiteDatabase(filePath))
{
Tools = db.GetCollection<ExternalTools>("externalTools");
if (Tools.Count() == 0)
{
CreateToolList();
// Index document using document Name property
Tools.EnsureIndex(x => x.Name);
}
}
Debug.WriteLine(Tools.Count());
var temp = Tools.FindAll(); // null error
var test = Tools.FindById(1); // another null error
Debug.WriteLine(test.Name); //
}
Thanks!
Well, I figured it out (so many hours of debugging wasted!) My code is in the wrong spot, if I move it into the using statement it works just fine. I suspect this has to do with the fact that on the first run it's adding stuff into the colection so it has the proper reference. Regardless, this code works:
using (var db = new LiteDatabase(filePath))
{
Tools = db.GetCollection<ExternalTools>("externalTools");
if (Tools.Count() == 0)
{
CreateToolList();
// Index document using document Name property
Tools.EnsureIndex(x => x.Name);
}
Debug.WriteLine(Tools.Count());
var temp = Tools.FindAll(); // null error
var test = Tools.FindById(1); // another null error
Debug.WriteLine(test.Name); //
}
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 8 years ago.
I am just starting to learn C# in In Visual Studios 2010, and using Bob Tabor's LearnVisualStudio.Net to help. I am on Day 3's homework and wanted to get extra practice in creating classes and defining public and private variables in them and then creating string statements that can be collected into one of the classes for a Console.Write method that the program will display. I feel I have created the public and private variables fine, and even the string statements, but when I go to gather them up and print them, I get an error statement: NullReferenceException was unhandled. I don't know what I am doing wrong. I have pasted the important parts (I think) of each class below.
In the Motorcycles class:
public string GetMotorcycleInfo()
{
string message = "";
message = "A " + Make + " " + Model + " " + EngineSize + " " + "is fast, but ` expensive at "
+ Cost + "!";
return message;
}
in the Bicycles class:
public string GetBikeInfo()
{
string message = "";
message = "A " + Brand + " " + BikeType + NumberOfGears + "bicycle";
return message;
}
In the Mopeds class:
public Motorcycles Cycles
{
get { return motorcycles; }
set { motorcycles = value; }
}
public Bicycles Bikes
{
get { return bicycles; }
set { bicycles = value; }
}
public void DisplayInfo()
{
Console.Write("A " + Cycles.GetMotorcycleInfo());
//Console.Write(" is fast, but expensive.");
Console.Write("A " + Bikes.GetBikeInfo());
//Console.Write(" is slow, but steady.");
Console.Write("But a " + Make + " " + Model + " Moped, with " + Mpg
+ "mpg, and costing only " +
Cost + " is a deal you don't want to pass up!");
}
And, in the Program class:
class Program
{
static void Main(string[] args)
{
Motorcycles myBBBike = new Motorcycles();
myBBBike.Make="Harley Davidson";
myBBBike.Model="Golden Sun";
myBBBike.EngineSize="650 cc";
myBBBike.Cost="$30,000";
Bicycles mySBSBike = new Bicycles();
mySBSBike.Brand = "Schwin";
mySBSBike.NumberOfGears = 10;
mySBSBike.BikeType = "Off Road";
mySBSBike.Price = "$500.00";
Mopeds myMopeds = new Mopeds();
myMopeds.Make = "Renegade";
myMopeds.Model = "TPGS-805";
myMopeds.Mpg = "75 mpg";
myMopeds.Cost = "$599.00";
myMopeds.DisplayInfo();
Console.ReadLine();
}
}
}
Any suggestions would be appreciated. Thank you
You haven't added the bicycles or Motorcycles to the myMopeds instance yet:
add this before your myMopeds.DisplayInt();
myMopeds.Bikes = mySBSBike;
myMopeds.Cycles = myBBBike;
In addition, you should get your naming conventions straight. A single motorcycle is a Motorcycle, not a Motorcyles. This pluralization is confusing for others and for yourself. You should change your class naming conventions to match this as well, so public class Motorcycle,public class Bicycle, etc.
You'll need to post the variables. The NullReferenceException happens when you try to reference something that is null (pretty self-explanatory).
My guess is you're never setting your Cycles or Bikes references to an instance of that class.
You'll either need to manually assign them after you instantiate your Mopeds class:
myMopeds.Bikes = mySBSBike;
myMopeds.Cycles = myBBBike;
Or you can add them as a constructor parameter to your Mopeds class
public Mopeds(Bicyles b, Motorcycles m) {
this.Bikes = b;
this.Cycles = m;
}
And create your Mopeds class like so:
Mopeds myMopeds = new Mopeds(mySBSBikes, myBBBike);
There are lots of ways to go about it; however you go about it though, you have to actually gives those variables a value otherwise they'll always be null!
Also, like the user above me pointed out, you should definitely get your naming conventions correct, the pluralizing can be a bit confusing.
I have an object which contains 2 pieces of information in objData[0]. The information is System_ID and Network_ID. The data is coming from a query to a database.
I want to get the data out of the object and display it in two separate text boxes, one for system_ID and one for Network_ID. Right now I am putting them into a combo box.
See below my code:
//get network ID and systenm name
private void cmbAddItem_SelectedIndexChanged(object sender, EventArgs e)
{
FASystems fSys = new FASystems(sConn);
object objData = fSys.getSystemNetworkIDFriendlyName(cmbAddItem.Text.ToString());
cmbNetworkID.DataSource = objData;
cmbNetworkID.DisplayMember = "Network_ID";
cmbSysName.DataSource = objData;
cmbSysName.DisplayMember = "System_Name";
// txtNetworkID.Text = objData[0].Network_ID;
}
Assuming your C# compiler is 3.0 or up use the var keyword on the api call
var objData = fSys.getSystemNetworkIDFriendlyName(cmbAddItem.Text.ToString());
Let's assume you're correct that there is an array now in objData with a type in it that has at least Network_ID as a member...
txtNetworkID.Text = objData[0].Network_ID;
should work then.
Can you post the function declaration for getSystemNetworkIDFriendlyName and show how you are populating the return type?
I recommend creating a new class to store the NetworkID and SystemID
class SystemInfo
{
public string NetworkID { get; set; }
public string SystemId { get; set; }
}
Rewrite the function getSystemNetworkIDFriendlyName to return an instance of SystemInfo. Then populating your textbox becomes:
FASystems fSys = new FASystems(sConn);
SystemInfo inf o= fSys.getSystemNetworkIDFriendlyName(cmbAddItem.Text.ToString());
txtNetworkID.Text = info.NetworkID;
Hope this helps,
KenC
In my app I am building my own media player. When a user selects a song to play want to be able to pass the link to the sample media and the metadata associated with it (Artist, Track, Album Art, etc.) The part I'm stuck on is how to group all the data and pass it to the media player page. Here's what i have so far.
Determine what item was selected and add data to query string.
UPDATED
public void musicSampleSelectedHandler(object sender, RoutedEventArgs e)
{
Track selected = (sender as Image).DataContext as Track;
ListBoxItem pressedItem = this.listReleaseMain.ItemContainerGenerator.ContainerFromItem(selected) as ListBoxItem;
if (pressedItem != null)
{
string _rT = selected.title;
string _rN = selected.release.name;
//string _rA = selected.artists; ????
string _rI = selected.images.large.url;
string _rS = selected.sampleUrl;
this.NavigationService.Navigate(new Uri("/Pages/MediaPage.xaml?releaseName=" + _rN + "&releaseTrack=" + _rT + "&releaseImage=" + _rI
+ "&releaseSample=" + _rS, UriKind.Relative));
}
}
OnNavigatedTo method to pull data out of the query string
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
string releaseName = String.Empty;
string releaseImg = String.Empty;
string releaseUrl = String.Empty;
if (NavigationContext.QueryString.TryGetValue("releaseUrl", out releaseUrl))
{
sampleMedia.Source = new Uri(releaseUrl, UriKind.Absolute);
}
}
I'm not sure if I can use the query sting to pass multiple pieces to the media player, or if I to do something different to pass the data to the other page. All of my data comes from the web using a webclient. Thanks for the help.
QueryString is just a Dictionary of the parameters passed in via the Uri. The Uri uses the standard syntax of passing in parameters delimited by &. So in your example, if you had something like:
this.NavigationService.Navigate(new Uri("/Pages/MediaPage.xaml?releaseUrl=" + releaseUrl + "&releaseImg=" + releaseImg , UriKind.Relative));
then you can then parse this out using something like:
if (NavigationContext.QueryString.TryGetValue("releaseUrl", out releaseUrl))
{
sampleMedia.Source = new Uri(releaseUrl, UriKind.Absolute);
}
if (NavigationContext.QueryString.TryGetValue("releaseImg", out releaseImg))
{
// do something with releaseImg
}
I am able to create controls pro grammatically using the code below without issue:
FileListReader fReader = (FileListReader)LoadControl("~/Controls/FileListReader.ascx");
phFileLists.Controls.Add(fReader);
However, I would like to change the control so that I can give it a constructor like this:
public FileListReader(Int32 itemGroupId, Int32 documentType, String HeaderString, String FooterString, bool isAdminUser)
{
base.Construct();
this.itemGroupId = itemGroupId;
this.documentType = documentType;
this.HeaderString = HeaderString;
this.FooterString = FooterString;
this.isAdminUser = isAdminUser;
}
and then I should be able to call the control like this:
FileListReader fReader = (FileListReader)LoadControl(typeof(FileListReader), new Object[] { itemGroupId, 6, "Sell Sheets", "<br /><br />", isAdminUser });
However, when I do this I always get an error that my in page controls within my FileListReader Control have not been instantiated and I get a null reference error. So for example I have an <asp:Label></asp:label> control that errors out when I try to set it's text on the Page_Load method. What is causing this? I figured the base.Construct() would have solved this issue but it obviously has not.
The proper way to inherit a constructor is like this:
class FileListReader : WebControl
{
public FileListReader(Int32 itemGroupId,
Int32 documentType,
String HeaderString,
String FooterString,
bool isAdminUser) : base() // <-- notice the inherit
{
this.itemGroupId = itemGroupId;
this.documentType = documentType;
this.HeaderString = HeaderString;
this.FooterString = FooterString;
this.isAdminUser = isAdminUser;
}
// ... other code here ... //
}
Does changing your constructor like that fix the issue?
I am not sure that calling base.Contruct() is what you should be doing, try calling the default contructor of the base class example below:
public FileListReader(Int32 itemGroupId, Int32 documentType, String HeaderString, String FooterString, bool isAdminUser) :base()
{
base.Construct();
this.itemGroupId = itemGroupId;
this.documentType = documentType;
this.HeaderString = HeaderString;
this.FooterString = FooterString;
this.isAdminUser = isAdminUser;
}