I'm working on a project to develop a UWP app.
I'm getting the above mentioned error when I click a button intended to navigate to another frame.
Here's the code of the first frame:
private void Search_Click(object sender, RoutedEventArgs e)
{
Submit();
}
void Submit()
{
DateTime? pickupdate;
pickupdate = PickupDate.Date.DateTime;
DateTime? retdate;
retdate = ReturnDate.Date.DateTime;
Reservation res = new Reservation(pickupdate.Value.ToString("dd-MM-yyyy"), retdate.Value.ToString("dd-MM-yyyy"));
Frame.Navigate(typeof(Reservation));
}
And the code for the second frame:
public Reservation(string pickup, string _return)
{
InitializeComponent();
PickupDateDisplay.Text = pickup;
ReturnDateDisplay.Text = _return;
}
UPDATE:
Ok so I overloaded the Reservation() constructor and now the code for the second frame looks like this:
public Reservation()
{
InitializeComponent();
}
public Reservation(string pickupdate,string retdate)
{
InitializeComponent();
PickupDateDisplay.Text = pickupdate;
ReturnDateDisplay.Text = retdate;
}
Now I don't get any errors on runtime but the PickupDateDisplay.Text and ReturnDateDisplay.Text does not change
This is happening because the Frame.Navigate method that is used for navigation uses parameter less constructor of the given page. To pass parameters to the target page you should use this overload of the method.
void Submit()
{
DateTime? pickupdate = PickupDate.Date.DateTime;
DateTime? retdate = ReturnDate.Date.DateTime;
// This is useless, this instance is not used anywhere (Frame.Navigate creates its own new instance)
// Reservation res = new Reservation(pickupdate.Value.ToString("dd-MM-yyyy"), retdate.Value.ToString("dd-MM-yyyy"));
string[] parameters = { pickupdate.Value.ToString("dd-MM-yyyy"), retdate.Value.ToString("dd-MM-yyyy") };
Frame.Navigate(typeof(Reservation), parameters);
}
Reservation page:
string[] parameters;
public Reservation()
{
Loaded += (sender, e) =>
{
PickupDateDisplay.Text = parameters[0];
ReturnDateDisplay.Text = parameters[1];
}
InitializeComponent();
}
// This ctor is useless too
// public Reservation(string pickupdate,string retdate)
// {
// InitializeComponent();
// PickupDateDisplay.Text = pickupdate;
// ReturnDateDisplay.Text = retdate;
// }
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
parameters = (string[])e.Parameter;
}
Related
I am trying to call this GetProductStatus() method on a page button click event, but it's loading before the button click. Means when the ViewModel is loading, this is also load automatically.
I would like to declared this VM method "GetProductStatus()" to be called only when a button click event occurs.
ViewModel method:
private async void GetProductStatus()
{
try
{
IsBusy = true;
var status = await ProductStatusService.GetProductStatus(new ProductStatus()
{
StoreCode = s_code,
StartTime = StartDateValue.AddMinutes(time1),
EndTime = StartDateValue.AddMinutes(time2)
});
IsBusy = false;
if (status != null)
{
//Process happens
}
else
{
//Array is Null
}
ProductStatus = status;
}
catch (Exception)
{
ProductStatus = null;
}
}
Here, the method is declared.
public ProductViewModel(INavigation nav, Store store)
{
_Nav = nav;
GetProductStatus();
}
Here, the clicked event.
private async void ProductTypeButton_Clicked(object sender, EventArgs e)
{
await Navigation.PushAsync(new ProductPage(_ViewModel));
}
I would like to declared this VM method "GetProductStatus()" to be
called only when a button click event occurs.
private async void ProductTypeButton_Clicked(object sender, EventArgs e)
{
await Navigation.PushAsync(new ProductPage(_ViewModel));
}
For above code you posted, we can find that the constructor of your viewmodel will be called as soon as you call code new ProductPage(_ViewModel).
So, you can try to remove code GetProductStatus(); in constructor ProductViewModel
public ProductViewModel(INavigation nav, Store store)
{
_Nav = nav;
// remove code here
//GetProductStatus();
}
and add a command in your ViewModel, and bind it to the button in your page.
Please refer to the following code:
public class ProductViewModel
{
public Command LoadDataCommand { get; set; }
public ProductViewModel() {
LoadDataCommand = new Command(loadData);
// remove code here
//GetProductStatus();
}
private void loadData()
{
GetProductStatus(); // add your code here
}
private async void GetProductStatus()
{
// other code
}
}
Note:
1.In this condition, you can also navigate as follows:
private async void ProductTypeButton_Clicked(object sender, EventArgs e)
{
await Navigation.PushAsync(new ProductPage(_ViewModel));
}
2.I don't add parameter to the constructor of ProductViewModel , you can modify above code I posted according to your needs.
Set aside the fact that you are working with views and models. Simply think of them like any other class in c#.
If you need to tell class A "do something under these circumstances`, what are your options?
Pass a parameter in constructor: public ProductViewModel(..., bool doGetProductStatus)..., usage: new ProductViewModel(..., true);
Call a method A.DoSomething(); after you've created it: _ViewModel.DoSomething();
Use MessagingCenter Publish/Subscribe.
The page where the user clicks either 1 or 2 and you get pushed to the same page, but I want it to be a unique list for each category clicked. So, when you click on Clickthis1 you'll get a ListView only Clickthis1 people can access and if you click on Clickthis2 you'll get a list only visible if you clicked Clickthis2.
void Clickthis1 (object sender, EventArgs args)
{
var CategoryName = new StartPage();
CategoryName.TheCategoryName ("Beatrice", /* the list here?*/);
Navigation.PushAsync (CategoryName);
}
void Clickthis2 (object sender, EventArgs args)
{
var CategoryName = new StartPage();
CategoryName.TheCategoryName ("Anna", /* the list here?*/);
Navigation.PushAsync(CategoryName);
}
And this is the page where the info gets pushed into and where I have the list. I am not sure how I should proceed however.
List<createSomething> ourPitems = new List<createSomething>();
public StartPage ()
{
InitializeComponent ();
}
public class createSomething
{
public string ourUsername {get; set;}
}
public void TheCategoryName (String pHeader, /*New list added here???*/)
{
personHeader.Text = pHeader;
}
protected override void OnAppearing(){
getItems (); }
async void getItems ()
{
var getItems = await parseAPI.myInfo (Application.Current.Properties
["sessionToken"].ToString ());
EmployeeList.ItemsSource = null;
ourPitems = new List<createSomething> ();
foreach (var currentItem in getItems["results"])
{
ourPitems.Add (new createSomething ()
{
ourUsername = currentItem ["YourName"].ToString (),
});}
EmployeeList.ItemsSource = ourPitems;
}
If you choose to use public properties instead of overloading your constructor:
In your calling page (StartPage?), pass in the Category Name:
void Clickthis1 (object sender, EventArgs args)
{
startPage= new StartPage();
startPage.CategoryName = categoryName;
Navigation.PushAsync (startPage));
}
Then in your second page (which I'll call ListPage)
class ListPage : ContentPage
{
public ListPage()
{
getItems ();
}
private string categoryName;
public string TheCategoryName
{
get { return categoryName; }
set { categoryName= value; }
}
Then use the category in your list-building method:
async void getItems ()
{
var items = await parseAPI.myInfo (Application.Current.Properties[categoryName].ToString ());
...
}
I am developing a Windows phone App and in my MainPage.xaml.cs file I have one private member that is being changed in the overrided method OnNavigateTo(). Although its value is changed, after that in the MainPage constructor its value resets to 0 (It's an int member). I guess that OnNavigateTo() method is being called BEFORE the constructor but if so I would have a nullReferenceException. What can cause that problem?
The OnNavigateTo() Function:
if (NavigationContext.QueryString.ContainsKey("leftDuration"))
{
//Get the selected value from IntroductionPage as a string
var leftRecievedInformation = NavigationContext.QueryString["leftDuration"];
//Convert the string to an enum object
var firstRunLeftChosenDuration = (LensLifetime)Enum.Parse(typeof(LensLifetime), leftRecievedInformation);
//Set the leftDuration value to the model object
_firstRunLeftDuration = getDurationAsNumber(firstRunLeftChosenDuration);
MessageBox.Show(_firstRunLeftDuration + "");
model.Left.LifeTime = _firstRunLeftDuration;
}
My problematic member is the _firstRunLeftDuration value. Although, as you can see, i set the model.Left.LifeTime value, in the MainPage.xaml I still get the default 0 value... It' like completely ignoring this line of code.. I know the code is not particularly clear but I don't think its beneficial to add extra lines of useless code.
Here's the MainPage.xaml.cs file:
public partial class MainPage : PhoneApplicationPage
{
public ContactLensesModel model;
private int _firstRunLeftDuration, _firstRunRightDuration; //Members used for the initialization of the app
public int FirstRunLeftDuration
{
get
{
return _firstRunLeftDuration;
}
set
{
_firstRunLeftDuration = value;
}
}
public int FirstRunRightDuration
{
get
{
return _firstRunRightDuration;
}
set
{
_firstRunRightDuration = value;
}
}
public ContactLensesModel Model
{
get
{
return model;
}
set
{
model = value;
}
}
// Constructor
public MainPage()
{
InitializeComponent();
// Sample code to localize the ApplicationBar
BuildLocalizedApplicationBar();
//Should check if the user starts the app for the first time....
//Create a new model
Model = new ContactLensesModel();
Model.setLeftNewStartingDate();
Model.setRightNewStartingDate();
//Should load the already saved model if the user in not entering for the first time...
//....
//....
loadModel();
//Connect the data Context
leftLensDaysRemaining.DataContext = Model.Left;
rightLensDaysRemaining.DataContext = Model.Right;
}
private int getDurationAsNumber(LensLifetime duration)
{
if (duration.Equals(LensLifetime.Day))
return 1;
else if (duration.Equals(LensLifetime.Two_Weeks))
return 14;
else
return DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month);
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
//Get the arguments as strings and convert them to an enum, is true only when the user enters app for the first time.
if (NavigationContext.QueryString.ContainsKey("leftDuration"))
{
//Get the selected value from IntroductionPage as a string
var leftRecievedInformation = NavigationContext.QueryString["leftDuration"];
//Convert the string to an enum object
var firstRunLeftChosenDuration = (LensLifetime)Enum.Parse(typeof(LensLifetime), leftRecievedInformation);
//Set the leftDuration value to the model object
FirstRunLeftDuration = getDurationAsNumber(firstRunLeftChosenDuration);
Model.Left.LifeTime = FirstRunLeftDuration;
}
if (NavigationContext.QueryString.ContainsKey("rightDuration"))
{
//Get the selected value from IntroductionPage as a string
var rightRecievedInformation = NavigationContext.QueryString["rightDuration"];
//Convert the string to an enum object
var firstRunRightChosenDuration = (LensLifetime)Enum.Parse(typeof(LensLifetime), rightRecievedInformation);
//Set the leftDuration value to the model object
_firstRunRightDuration = getDurationAsNumber(firstRunRightChosenDuration);
Model.Right.LifeTime = _firstRunRightDuration;
}
}
/// <summary>
/// Loads the model from the isolated Storage
/// </summary>
private void loadModel()
{
//Load the model...
}
private void BuildLocalizedApplicationBar()
{
// Set the page's ApplicationBar to a new instance of ApplicationBar.
ApplicationBar = new ApplicationBar();
// Create a new button and set the text value to the localized string from AppResources.
ApplicationBarIconButton appBarSettingsButton = new ApplicationBarIconButton(new Uri("/Assets/Icons/settingsIcon4.png", UriKind.Relative));
appBarSettingsButton.Text = AppResources.AppBarSettingsButtonText;
appBarSettingsButton.Click += appBarButton_Click;
ApplicationBar.Buttons.Add(appBarSettingsButton);
// Create a new menu item with the localized string from AppResources.
//ApplicationBarMenuItem appBarMenuItem = new ApplicationBarMenuItem(AppResources.AppBarMenuItemText);
//ApplicationBar.MenuItems.Add(appBarMenuItem);
}
void appBarButton_Click(object sender, EventArgs e)
{
NavigationService.Navigate(new Uri("/SettingsPage.xaml", UriKind.RelativeOrAbsolute));
}
private void leftButtonChange_Click(object sender, RoutedEventArgs e)
{
model.setLeftNewStartingDate();
}
private void rightChangeButton_Click(object sender, RoutedEventArgs e)
{
model.setRightNewStartingDate();
}
}
}
The OnNavigatedTo method cannot be called before the constructor. The constructor is always executed first. I think your model.Left.LifeTime doesn't raise a PropertyChanged event. Hence, your View won't know you are giving it a value. Therefore it will show the default value of model.Left.Lifetime which is probably 0.
On the other hand, it's hard to tell without seeing the rest of your code.
I'm probably missing something simple, but have been messing with this for a few hours and I cannot get the method to return something not null. When I'm stepping over the process, getDir1 will take the value of the class "swSheetFormatCycle.Form1.FolderUpdate", but getDir1.SwDir remains null so swDir remains null. Will the button method not set swDir or swTemplate the way I'm doing it?
// Get-Set Class
public class FolderUpdate
{
private string swDir;
public string SwDir
{
get {return swDir;}
set {swDir = value;}
}
private string swTemplate;
public string SwTemplate
{
get {return swTemplate;}
set {swTemplate = value;}
}
}
private void btnTemBrow_Click(object sender, EventArgs e)
{
OpenFileDialog tempBrowse = new OpenFileDialog();
DialogResult result = tempBrowse.ShowDialog();
string tempText = tempBrowse.FileName;
txtTemp.Text = tempText;
// Setting the template field
FolderUpdate temUpd = new FolderUpdate();
temUpd.SwTemplate = tempText;
}
private void btnDirBrow_Click(object sender, EventArgs e)
{
FolderBrowserDialog dirBrowse = new FolderBrowserDialog();
DialogResult result = dirBrowse.ShowDialog();
string dirText = dirBrowse.SelectedPath;
txtDir.Text = dirText;
// Setting the directory field
FolderUpdate dirUpd = new FolderUpdate();
dirUpd.SwDir = dirText;
}
// Get the directory set by the button method
swSheetFormatCycle.Form1.FolderUpdate getDir1 = new swSheetFormatCycle.Form1.FolderUpdate();
string swDir = getDir1.SwDir;
// Get the template set by the button method
swSheetFormatCycle.Form1.FolderUpdate getDir2 = new swSheetFormatCycle.Form1.FolderUpdate();
string swTemplate = getDir2.SwTemplate;
Your button events are creating new instances of your FolderUpdate class and then are not doing anything with the object and it is abandoned at the end of the method call.
your "// Get the directory set by the button method" code
is also creating new instances so they will also be null
Attach the FolderUpdate instance to the form itself so that you can reference it.
public class FolderUpdate
{
....
}
public FolderUpdate Folders { get; set; }
private void btnTemBrow_Click(object sender, EventArgs e)
{
...
Folders.SwTemplate = tempText;
}
private void btnDirBrow_Click(object sender, EventArgs e)
{
...
Folders.SwDir = dirText;
}
// Then when you are reading them
var folders = swSheetFormatCycle.Form1.Folders;
string swDir = folders.SwDir;
string swTemplate = folders.SwTemplate;
I just started to use awesomium.
I wanted to understand how to change user-agent and referrer.
i need for example to initialize 5 istance o awesomium webcontrol and for each of them i need different user-agent and different referrer.
this is my simple code
private void newbrowser()
{
browser = new Awesomium.Windows.Forms.WebControl();
browser.Paint += browser_Paint;
browser.Location = new System.Drawing.Point(1, 1);
browser.Name = "webControl";
browser.Size = new System.Drawing.Size(1024, 768);
browser.Source = new System.Uri("https://www.google.com/", System.UriKind.Absolute);
browser.TabIndex = 0;
}
void browser_Paint(object sender, PaintEventArgs e)
{
browser.Paint -= browser_Paint;
System.Collections.Specialized.NameValueCollection myCol =
new System.Collections.Specialized.NameValueCollection();
myCol.Add("Referer", "http://www.yahoo.com");
browser.SetHeaderDefinition("MyHeader", myCol);
browser.AddHeaderRewriteRule("http://*", "MyHeader");
}
private void button1_Click(object sender, EventArgs e)
{
newbrowser();
}
these 2 lines give an error
browser.SetHeaderDefinition("MyHeader", myCol);
browser.AddHeaderRewriteRule("http://*", "MyHeader");
Error 1 'Awesomium.Windows.Forms.WebControl' does not contain a
definition for 'SetHeaderDefinition'
Error 1 'Awesomium.Windows.Forms.WebControl' does not contain a
definition for 'AddHeaderRewriteRule'
thanks for the help
You need to set the user agent of the WebCore that governs your WebControl. This must be done before you create your WebControl.
public WebForm()
{
if ( !WebCore.IsRunning )
WebCore.Initialize( new WebConfig() { UserAgent = "YourUserAgent" } );
InitializeComponent();
}
My solution - is wrapper around WebBrowser, that implements IResourceInterceptor and can navigate with any additional headers:
public class class BrowserWrapper : IResourceInterceptor
{
public BrowserWrapper()
{
WebCore.ResourceInterceptor = this;
//BrowserWrapper can contains WebBrowser or knows how to delegate him Naviagtion (Source property)
}
private readonly ConcurrentDictionary<Uri, string> headers = new ConcurrentDictionary<Uri, string>();
public void Navigate(Uri uri, string additionalHeaders = null)
{
if (additionalHeaders != null) headers.AddOrUpdate(uri, additionalHeaders, (url, h) => h);
//Navigation to browser (WebControl.Source = uri...)
}
ResourceResponse IResourceInterceptor.OnRequest(ResourceRequest request)
{
string h;
if (headers.TryRemove(request.Url, out h))
{
var hs = h.Split(':');
request.AppendExtraHeader(hs[0], hs[1]);
}
return null;
}
bool IResourceInterceptor.OnFilterNavigation(NavigationRequest request)
{
return false;
}
}