I have an AppBar with a button that launches a popup that contains a list that the user selects and upon one being selected it refreshes the page, but before it refreshes for a certain page I need it to execute a task. The code works great on my other pages. I just need it to execute
await home.DatabaseTest();
before it refreshes the page and I only want it to execute if the current page is Dashboard
private async void customerNamePopUp_Tapped_1(object sender, TappedRoutedEventArgs e)
{
//Gets the selected Customer Name and stores it in the Database.
barCustomerName = db.selectCustomerNumberByCustomerName(customerNamePopUp.SelectedItem);
rh.appDataHandler(customerNamePopUp.SelectedIndex, barCustomerName);
if ("WHAT DO I PUT HERE TO TEST IF PAGE EQUALS DASHBOARD")
{
await home.DatabaseTest();
}
if (this.Frame != null)
{
//Refreshes Current Page
Frame1.Navigate(Frame1.Content.GetType(), RootPage);
}
}
See note in loop before the await task to know what I am asking for.
Thank you
Create a public enum where each item correlates to each page.
On the App page create a static property of the enum created which will signify the current page.
On each page's OnNavigatedTo method set the app static property to that page's enum.
Wherever needed check that variable for the current page.
I figured it out.
if (Frame1.Content.GetType() == typeof(Dashboard))
{
await home.DatabaseTest();
}
Related
I have a Blazor component named NavBar.razor that displays a Radzen navigation menu with a list of tags. When the user clicks a tag (RadzenPanelMenuItem), the component OrderBrowser.razor is loaded into the page next to the menu. The query string lets OrderBrowser.razor know what tag was selected. (See the OnInitializedAsync method below.) The component loads the associated orders into a grid.
This works fine the first time the user clicks a tag, but when they click a different tag, the OnInitializedAsync method does not execute, even though the uri changes. So I added an event handler to force a reload when the uri changes. This works, but, for some reason, it seems to reload twice, resulting in an undesirable blink when it reloads the 2nd time.
Does anyone know a better way to do this? Thanks.
Code from NavBar.razor:
#foreach (var item in TagsAndCounts)
{
<Radzen.Blazor.RadzenPanelMenuItem
Text="#(item.Tag + " (" + item.Count + ")")"
Path="#("orders/browse?tag=" + item.Tag)" />
}
Order grid from OrderBrowser.razor:
<OrderGrid Data="#orders" AllowPaging="false" />
Code from OrderBrowser.razor:
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
NavManager.LocationChanged += NavManager_LocationChanged;
var uri = NavManager.ToAbsoluteUri(NavManager.Uri);
if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("tag", out var tag))
{
orders = await orderService.GetOrdersForTagAsync(tag);
}
}
private void NavManager_LocationChanged(object sender, LocationChangedEventArgs e)
{
NavManager.NavigateTo(NavManager.Uri, forceLoad: true);
}
Use this event
[Parameter]
[SupplyParameterFromQuery]
public string? Page { get; set; } = "0";
protected override void OnParametersSet()
{
//Fire your Code her
}
When you go from: yourUrl/tag/tagname1 and click to link yourUrl/tag/tagname2 it does not fire OnInitializedAsync, because new page was not created. It is intended and correct behavior. But bit confusing.
You can leverage new, with .net6 introduced, capability of SupplyFromQueryParameter attribute, which will change its value based on query string.
[Parameter, SupplyParameterFromQuery(Name = "tag")] public string Tag { get; set; } = "";
Now you can do the magic inside seeter of the Tag property. Or, if you need to call async method inside setter (which is not a good practice), you can use OnParametersSet method. It is called right after parameters has been changed. So you also need a mechanism to check if tag parameter has been changed (because it is called every time *some* parameter has been changed )
bool tagUpdated = true;
string _tag ="";
[Parameter,SupplyParameterFromQuery] public string Tag { get => _tag; set { if (value != _tag) { _tag = value; tagUpdated = true; } } }
protected override async Task OnParametersSetAsync()
{
if (tagUpdated)
{
tagUpdated = false;
await YourAsyncCallAndOtherMagic();
}
}
Note, that SupplyFromQueryParameter works only on pages (.razor components with #page directive)
(still not the most beautiful solution I guess. Open for suggestions...)
I found a solution. It's still a bit of a hack, but it seems to work. If anybody has any better solutions, please let me know. I just changed the event handler to get the new URL and update the page, instead of forcing a reload.
private async void NavManager_LocationChanged(object sender, LocationChangedEventArgs e)
{
orders = await orderService.GetOrdersForTagAsync(tag);
var index = NavManager.Uri.LastIndexOf("/");
tag = NavManager.Uri.Substring(index + 1);
if (tag != "open_orders")
{
StateHasChanged();
}
}
I'm trying to programmatically login to a site like espn.com. The way the site is setup is once I click on the Log In button located on the homepage, a Log In popup window is displayed in the middle of the screen with the background slightly tinted. My goal is to programmatically obtain that popup box, supply the username and password, and submit it -- hoping that a cookie is returned to me to use as authentication. However, because Javascript is used to display the form, I don't necessarily have easy access to the form's input tags via the main page's HTML.
I've tried researching various solutions such as HttpClient and HttpWebRequest, however it appears that a Webbrowser is best since the login form is displayed using Javascript. Since I don't necessarily have easy access to the form's input tags, a Webbrowser seems the best alternative to capturing the popup's input elements.
class ESPNLoginViewModel
{
private string Url;
private WebBrowser webBrowser1 = new WebBrowser();
private SHDocVw.WebBrowser_V1 Web_V1;
public ESPNLoginViewModel()
{
Initialize();
}
private void Initialize()
{
Url = "http://www.espn.com/";
Login();
}
private void Login()
{
webBrowser1.Navigate(Url);
webBrowser1.DocumentCompleted +=
new WebBrowserDocumentCompletedEventHandler(webpage_DocumentCompleted);
Web_V1 = (SHDocVw.WebBrowser_V1)this.webBrowser1.ActiveXInstance;
Web_V1.NewWindow += new SHDocVw.DWebBrowserEvents_NewWindowEventHandler(Web_V1_NewWindow);
}
//This never gets executed
private void Web_V1_NewWindow(string URL, int Flags, string TargetFrameName, ref object PostData, string Headers, ref bool Processed)
{
//I'll start determing how to code this once I'm able to get this invoked
}
private void webpage_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
HtmlElement loginButton = webBrowser1.Document.GetElementsByTagName("button")[5];
loginButton.InvokeMember("click");
//I've also tried the below InvokeScript method to see if executing the javascript that
//is called when the Log In button is clicked, however Web_V1_NewWindow still wasn't called.
//webBrowser1.Document.InvokeScript("buildOverlay");
}
}
I'm expecting the Web_V1_NewWindow handler to be invoked when the InvokeMember("click") method is called. However, code execution only runs through the webpage_DocumentCompleted handler without any calls to Web_V1_NewWindow. It might be that I need to use a different method than InvokeMember("click") to invoke the Log In button's click event handler. Or I might need to try something completely different altogether. I'm not 100% sure the Web_V1.NewWindow is the correct approach for my needs, but I've seen NewWindow used often when dealing with popups so I figured I should give it a try.
Any help would be greatly appreciated as I've spent a significant amount of time on this.
I know it is the late answer. But it will help someone else.
You can extract the value from FRAME element by following
// Get frame using frame ID
HtmlWindow frameWindow = (from HtmlWindow win
in WbBrowser.Document.Window.Frames select win)
.Where(x => string.Compare(x.WindowFrameElement.Id, "frm1") == 0)
.FirstOrDefault();
// Get first frame textbox with ID
HtmlElement txtElement = (from HtmlElement element
in frameWindow.Document.GetElementsByTagName("input")
select element)
.Where(x => string.Compare(x.Id, "txt") == 0).FirstOrDefault();
// Check txtElement is nul or not
if(txtElement != null)
{
Label1.Text = txtElement.GetAttribute("value");
}
For more details check
this article
I have a C# winform project that displays a list of results based on a user's search criteria. For each item on the list, the user can open a modeless dialog box showing more details about the selected item.
Every time the user opens an instance of my details window, this code runs:
public void showDetails()
{
GetDetails route = new GetDetails();
route.myParent = this;
route.Show();
}
In order to compare details between two or more items, the user is allowed to open as many instances of this dialog box as it likes. I'd like to be able to close any and all open instances of this window when the user conducts a new search from the main form window? I've tried Googling, but no luck ... does anyone know how to do this?
Application.OpenForms is a collection of open forms owned by the application
try find all details dialogs and close them like this:
foreach(var f in Application.OpenForms.OfType<GetDetails>().ToList())
{
f.Close();
}
You don't really tell, but I assume your GetDetails is a System.Windows.Forms.Control (probably a form, a dialog box, a message box, etc).
If you look closely to your Form.InitializeComponent, you'll see that Form has a property Controls. All child controls are added to the control collection.
If you add each created route to your control collection you can ask this collection for all objects of type GetDetails and order them to close:
public void ShowDetails()
{
var route = new GetDetails();
route.myParent = this;
this.Controls.Add(route);
route.Show();
}
public void CloseAllRoutes()
{
foreach (var route in this.Controls.Where( control => control is GetDetails))
{
route.Close();
}
}
You need to be certain that when a rout is closed, or disposed or something the following code is called:
private void OnRouteClosed (object sender, ...)
{
if (sender is GetDetails)
{
this.Controls.Remove(sender);
}
}
I am working on basic ASP.net website and i want to execute server side function when user try to go away from page. For this i am using onbeforeunload event of window. I have check box on my page and when user checked this check box, i am executing sverside "checkedchange event". Issue is whenever user click on this check box my web method is also get called, which should not get called as only postback is happen, user is not leaving my page. can any one suggest me to avoid web method call when postback happen.
I wnat to execute web method only in following scenarios:
1) When user closes the browser.
2) On click of “Find more matches” button, when user landed on search results page with no school listed.
3) when user changes the url from browser's address bar
Code on aspx page:
function GetMessage() {
var urlstring = document.URL;
{
PageMethods.Message( document.URL);
}
}
</script>
Code on aspx.cs page
[System.Web.Services.WebMethod]
public static void Message()
{
string x="a";
}
This link should hold the answer you are looking for: How to capture the browser window close event?
I think the following code from that link is what you are looking for.
var inFormOrLink;
$('a').live('click', function() { inFormOrLink = true; });
$('form').bind('submit', function() { inFormOrLink = true; });
$(window).bind('beforeunload', function(eventObject) {
var returnValue = undefined;
if (! inFormOrLink) {
//TODO: Execute some code before unload here
//returnValue = "Message to display before the user leaves the page.";
}
eventObject.returnValue = returnValue;
return returnValue;
});
private void btn_friends_pressed(object sender, RoutedEventArgs e)
{
NavigationService.Navigate(new Uri("/Friends.xaml", UriKind.Relative));
}
When I press the button I go to the Friends page, which loads many friends from isolated storage.Than I press "back" button and go to the Menu page, when I press again the button, I have "Operation not permitted on IsolatedStorageFileStream." message.
How I can not reload page and keep it in RAM.
Something like:
if (Friends.Page.IsRunning==true)
NavigationService.Navigate("/Friends.xaml");
else
NavigationService.Navigate(new Uri("/Friends.xaml", UriKind.Relative));
Whenever you navigate to a page, it is reloaded automatically. The pages themselves are not kept in memory once you've navigated away from them. If you want to store it memory, and not read it from Isolated Storage each time, then you can simply create a static class that contains a static List that stores your friends. Once you've loaded your friends, depending on their type, you can add it to the list. Whenever you need to access them, simply call it from the static List. For example, in your solution, create a new class:
using ... //your using directives
namespace MyApp //Your project Namespace
{
public static class FriendsStorage //rename `FriendsStorage` to whatever you want
{
public static List<Friends> ListOfFriends = new List<Friends>(); //Your list
}
}
To set it, you can load the information from IsolatedStorage and add it to the list:
foreach(Friend f in Friends)
FriendsStorage.ListOfFriends.Add(f);
Whenever you need to query the Friends list you can call it like this:
var friendList = FriendsStorage.ListOfFriends;
Even if you use the above method, you should try and fix the error you're getting. Can you post your Isolated Storage code?
If you want to get rid of the error message, you should use your stream in a using() block,
using (var stream = new IsolatedStorageFileStream(...))
{
// load your data here
}
Regarding saving page, it's generally not a good idea because your memory can exponentialy grow and your application will be very unresponsive.
Although you can always use your App.xaml.cs as a global instance of your application to cache some of your data sources:
List<Friend> _Friends;
List<Friend> _Friends
{
get
{
if(_Friends == null) _Friends = GetFriends();
return _Friends;
}
}
but if you did this be very careful not to store loads of data.