Custom Page Class w/ automated unload Event - c#

we have a rather large Silverlight application and we need to add some extra functionality to it.
The App consists of an Frame-Element and a TreeView w/ HyperlinkButtons for the navigation. Every content which will be loaded into the main Frame is a Page.
Now, I need to hook into every Page's unload event. Currently we use something like this:
/* PageX.xaml */
<navigation:Page
x:Class="Foo.Views.PageX"
<!-- namespacing -->
Title="Test Page X"
Unloaded="Page_Unloaded">
...
</navigation:Page>
Code-behind:
/* PageX.xaml.cs */
/* usings */
namespace Foo.Views
{
public partial class PageX : Page
{
public PageX() {
InitializeComponent();
}
private void Page_Unloaded(object sender, RoutedEventArgs e) {
/* CODE */
}
}
}
This approach need to be implemented on each and every Page, as the code within the unloaded method stays exactly the same... As I mentioned earlier, we have a couple of Pages and it would be much more useful to create a custom Page-class where this Page_Unloaded() is implemented directly, so that we don't need to alter every Page.
Can you please tell me how to create such a custom Page-class?
Thanks in advance for any help!!
Kind regards!

You could create a base Page class that all your pages inherit from which registers the event in the constructor...
public class BasePage : Page
{
public BasePage()
{
Unloaded += Page_Unloaded;
}
void Page_Unloaded(object sender, RoutedEventArgs e)
{
}
}
Then all your pages could inherit from that...
public partial class Page1 : BasePage
{
public Page1()
{
InitializeComponent();
}
}
...and in the xaml of each page...
<base:BasePage x:Class="WPFApp.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:base="clr-namespace:WPFApp">
<Grid>
</Grid>
</base:BasePage>

Related

TabbedPage - Call method when certain Tab is active

I have a scenario where I want to call a method when the user of the app navigates to a certain tab of the TabbedPage.
Example: If I navigate to tab no. 3 of my TabbedPage, a certain method shall be called.
How do I achieve that?
By default all tabs of the TabbedPage are loaded when I start the app.
I am writing in Xamarin - C#.
Best regards!
There are two sample ways to achieve that.
One is using OnAppearing method inside the needed item of tab page.
For example, the tab no. 3 of TabbedPage is ItemsPage, then its ItemsPage.xaml.cs code as follows:
public partial class ItemsPage : ContentPage
{
public ItemsPage()
{
InitializeComponent();
}
protected override void OnAppearing()
{
base.OnAppearing();
// Call your needed method here
}
}
The another way is using OnCurrentPageChanged methond inside the tabbedpage.xaml.cs.
For example, the code as follows:
public partial class MainPage : TabbedPage
{
public MainPage()
{
InitializeComponent();
}
protected override void OnCurrentPageChanged()
{
base.OnCurrentPageChanged();
if(CurrentPage.Title == "tab no. 3 title")
{
// call your needed method
}
//Console.WriteLine(CurrentPage.Title);
}
}

Navigate to a Default View when Application Loaded using Prism 7 in WPF

I follows samples code provided in https://github.com/PrismLibrary/Prism-Samples-Wpf/blob/master/17-BasicRegionNavigation
I want to achieve the following result when I run the application (without explicitly clicking Navigate to View A). Does anyone know how to do it?
I have tried adding Navigate("ViewA"); after this line. However, I cannot get the desired outcome. Is it because the module hasn't been initialized?
Thanks.
did you add your module to the modulecatalog using override method ConfigureModuleCatalog? take a look at here
Eventually I solve by adding the following code in MainWindow.xaml.cs
public partial class MainWindow
{
IRegionManager _regionManager;
public MainWindow()
{
InitializeComponent();
_regionManager = ServiceLocator.Current.GetInstance<IRegionManager>();
RegionManager.SetRegionManager(ContentRegion, _regionManager);
Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
_regionManager.RequestNavigate("ContentRegion", "ViewA");
}
}
Get idea from: https://github.com/MahApps/MahApps.Metro/issues/1020#issuecomment-44779574
I'm kinda late to the party here, but I also stumbled over the question of how to navigate to a default view during the applications startup.
I found two ways:
1. App decides the default view
This can be solved in the CreateShell()-override in the App-Class.
This is my CreateShell-Method:
/// <inheritdoc />
protected override Window CreateShell()
{
var window = this.Container.Resolve<MainWindow>();
window.Loaded += (sender, args) =>
{
var manager = this.Container.Resolve<IRegionManager>();
manager.RequestNavigate("ContentRegion", "ViewA");
};
return window;
}
2. ViewModel decides the default view
Add a constructor to MainWindowViewModel that looks like this:
public MainWindowViewModel(IRegionManager regionManager)
{
regionManager.RegisterViewWithRegion("ContentRegion", "ViewA");
}

Different Navigation Types Between Pages

I am trying to make an app with a Main Page that is a plain Content Page (i.e. no toolbar) which has a button that leads into a Navigation Page (with toolbar). I'm struggling to find any resources to help me out in this specific case.
I have tried the following. In my App.xaml:
public partial class App : Application
{
public App ()
{
InitializeComponent();
MainPage = new App5.MainPage();
Pallets = new NavigationPage(new Pallets()); //Error: 'Pallets' is a type but is used like a variable
}
...
}
Above is the error I get on Pallets. I could change Pallets for MainPage and write the whole app with Navigation pages, which I will do for now, but I would prefer not to.
In my MainPage.xaml.cs, I'm trying to switch the view when the button is clicked:
public partial class MainPage : ContentPage
{
...
async void Button_Clicked(object sender, EventArgs e)
{
await Navigation.PushAsync(new Pallets());
}
}
I have seen examples such as this that include Navigation Page to Navigation Page buttons, but not plain Content Page to Navigation Page buttons.

Error: No matching constructor found on type

I have a WPF application where I am using multiple forms. There is one main form which gets opened when we start the application which is know as MainWindow.xaml. This form then have multiple forms which gets opened depending on the user option. There is a form StartClassWindow.xaml. Currently I am working on this form so I want it to start directly instead of MainWindow.xaml. So to do this I changed the app.xaml startupuri:
<Application x:Class="Class.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DispatcherUnhandledException="Application_DispatcherUnhandledException"
StartupUri="StartClassWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>
But then it started giving error like below:
No matching constructor found on type 'Class.StartClassWindow'. You
can use the Arguments or FactoryMethod directives to construct this
type.' Line number '3' and line position '9'.
Here is the StartClassWindow.xaml.cs:
namespace Class
{
public partial class StartClassWindow : System.Windows.Window
{
public StartClassWindow(string classData)
{
InitializeComponent();
className = classData;
function();
}
//rest of the code.
}
}
You need to add a parameter-less constructor to your StartClassWindow like this:
public StartClassWindow(string classData)
{
InitializeComponent();
className = classData;
function();
}
public StartClassWindow()
{
}
Or if you don't want to have another constructor you can override the OnStartup method in the App.xaml.cs but you should remove the StartupUri="StartClassWindow.xaml" in your App.xaml first. Like below:
protected override void OnStartup(StartupEventArgs e)
{
StartClassWindow st = new StartClassWindow("");
st.Show();
}
"Normally", your constructor must be parameterless:
public Login()
But, since you are using dependency injection, like this:
public Login(IUserService userService)
The constructor isn't parameterless, and the framework cannot instantiate the page if it's not told how to.
For this there are a couple of options:
Remove service from constructor
Just like this, but you'll need to access the userservice differently:
public Login()
pre .net 4.8, 4.7, using Unity (or Prism)
You can use a dependency injection framework like Unity to register the components.
It is described here:
https://www.wpftutorial.net/ReferenceArchitecture.html
public class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
IUnityContainer container = new UnityContainer();
container.RegisterType<IUserService, UserService>();
MainWindow mainWindow = container.Resolve<MainWindow>();
mainWindow.Show();
}
}
Manual using Navigation Service
Manually navigate, and do your own construction:
NavigationService.Navigate(new LoginPage(new UserService);
As described here: https://learn.microsoft.com/en-us/dotnet/desktop/wpf/app-development/navigation-overview?view=netframeworkdesktop-4.8
.net 5 WPF, using built in DI
If you are using .net 5, here is a tutorial. Make sure to register both the window and the service:
https://executecommands.com/dependency-injection-in-wpf-net-core-csharp/
Here's an example:
private void ConfigureServices(ServiceCollection services)
{
services.AddScoped<IUserService,UserService>();
services.AddSingleton<MainWindow>();
}
private void OnStartup(object sender, StartupEventArgs e)
{
var mainWindow = serviceProvider.GetService<MainWindow>();
mainWindow.Show();
}

How to use methods not in CodeBehind via OnClick event?

I want to reuse the same method for several pages, for example for a logout button or a redirect.
Right now i'm writing the same method in every codebehind page.
How can i do this? In PHP i just include a file with common functions and i have access to it, but what is the approach in ASP.NET?
<asp:Button ID="logoutBtn" Text="Logout" runat="server"
CssClass="btn btn-default" OnClick="logoutBtn_Click" />
I want to access the method "logoutBtn_Click" from all pages in my project.
Create button click event handler method replica in app_code class file like
namespace DotNetMirror
{
public class CommonClass
{
public void CommonlogoutBtn_Click(object sender, EventArgs e)
{
//common logic code
}
}
}
Designer file:
<asp:Button ID="logoutBtn" Text="Logout" runat="server"
CssClass="btn btn-default" OnClick="logoutBtn_Click" />
CodeBehind:
protected void logoutBtn_Click(object sender, EventArgs e)
{
DotNetMirror.CommonClass obj = new DotNetMirror.CommonClass();
obj.CommonlogoutBtn_Click(sender, e);
}
You can have any number of button click events in pages but call the common method.
You can use app_code folder. Create a .cs file there.
Write you method there and call that method form you all of the pages.
public class Class1
{
public void abc()
{
}
}
and use it like this
Class1 c = new Class1();
c.abc();
Edit 1
Or you can use re-useable controls like user-controls or custom-controls and place it anywhere in you project.
Some basic examples
http://www.codeproject.com/Articles/1739/User-controls-in-ASP-NET
http://www.codeproject.com/Articles/87474/ASP-NET-Custom-Control
The way you include files in PHP, there are similar ways in ASP.NET(C#) to do that.
You can make a class and then you can use that class anywhere in the project, on any page you want by creating an instance of that class.
For example:
Public Class logout
{
public void logoutclick()
{
//your code goes here
}
}
and now in the other page just create an instance of the class and use the function inside that class
logout log = new logout();
log.logoutclick();

Categories

Resources