App I am trying to create in WPF/C# has quite a few buttons in a layout with a "TV screen" type panel above (its actually an FMS emulator for commercial aircraft). Many of the buttons change the layout, which are numerous TEXTBOXs on the tv screen. My question is: is there a provision to encapsulate the layouts in different classes/files and load them into the "tv screen" at the selection of the various buttons? In other words, user hits the Flight Plan button and the layout of the 355x355 box (screen) above loads the XAML "flight_plan" layout/file/class. Each layout has different TEXTBOX sizes & locations and there are in excess of 30 different "pages", which would make encapsulating them desirable.
I am very new to WPF and c#, but have written win apps in c++ all the way back to Turbo C & OWL. I also may be trying to do something that isn't possible due to working lately in Android/Java and am confusing capabilities.
Thanks in advance.
Edit
Thanks to #adityaswami89 and everyone else who got me on the right track, I have found the solution. I added the pages via a new "WPF Page" in VS2012. Then changed the "screen" to a navigation frame and it was truly simple from there. Below is the simple project I created to test it.
public partial class MainWindow : Window
{
NavRad navrad = new NavRad();
FPlan fplan = new FPlan();
public MainWindow() {..}
private void Frame_Navigated_1(object sender, NavigationEventArgs e) {..}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
Screen_Frame.Navigate(fplan);
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
Screen_Frame.Navigate(navrad);
}
You can also use the concept of Frames for the intended functionality , if that can be an option you are looking.
You can refer the below link for the same.
http://msdn.microsoft.com/en-us/library/ms750478.aspx#Frame_in_Standalone_Applications
You can abstract the different UI Layout Sets within different User Controls and load them according your UI logic. One way to do this is using an MVVM framework, for example, Caliburn Micro makes this a pretty simple task as doing:
ActivateItem(UILayoutViewModel);
And this call can be called from any method.
See more of Caliburn Screens and Composition at official source.
Related
I'm studying to become a developer; as a formative project, I'm working on a desktop app to help me organize local amateur chess tournaments with MAUI. Basically, I want to be able to open multiple windows during the same execution, so that I can run various parallel tournaments on the same machine.
On the MainPage I placed a button that creates a new window that displays the NewTournamentPage
private void NewTournamentButton_Clicked(object sender, EventArgs e)
{
Application.Current.OpenWindow(new Window()
{
Page = new NewTournamentPage()
}) ;
}
in the NewTournamentPage I placed a button to add a new player to the tournament, and I want the window to freeze until the user inserts the player name, but without blocking the execution of the other windows. DisplayPromptAsync seems to be exactly what I'm looking for, so I did this:
public async void AddNewPlayer_Clicked(object sender, EventArgs e)
{
string newPlayerName = await this.DisplayPromptAsync("Add new Player", "Name:");
//code to add player to tournament
...
}
When I execute and click the NewTournamentButton multiple times, the windows are created with no problems, and they all work independently from each other, but when I press the AddNewPlayer button, the popup pops on the MainPage window, not on the one calling the method, and it takes and saves the input in newPlayerName; then, the same thing happens on all secondary windows, in order of creation, without updating newPlayerName. What is happening here? What am I missing?
Yes, it is just the case as you said. And I have created a new issue about this problem on github.
You can follow it up here: https://github.com/dotnet/maui/issues/7650.
Thanks for your feedback and support for maui very much.
I apologize if the question title isn't really specific, I'm not exactly sure how to condense the problem I'm having down to a few words. But to simplifiy the problem I'm having, here is my issue:
I'm creating a tool using WPF that consists of a TextBox that will contain a path to a directory and a Button that will allow you to Browse to a certain directory. Now, when I select the Browse button, it pops up a dialog, allows the user to select a directory and then I have some methods that will disable some buttons and updates some Brushes on the screen if the path doesn't meet a certain set of criteria. No problems there, got that working.
My problem is the TextBox that this Browse button correlates with. This TextBox is using a binding as such:
In my MainWindow.xaml (Yes, this is the simplified, focused version):
<Window>
<TextBox Text="{Binding Directory}" TextChanged="Directory_TextChanged" />
<Button Content="Browse..." Click="Browse_Click"/>
</Window>
In my code MainWindow.xaml.cs file:
public partial class MainWindow: Window
{
private ViewModel myViewModel;
public MainWindow()
{
myViewModel = new ViewModel();
this.DataContext = myViewModel;
}
private void Browse_Click(object sender, RoutedEventArgs e)
{
// Dialog stuff that's working
viewModel.Directory = dialog.SelectedPath;
}
private void InstallDir_TextChanged(object sender, TextChangedEventArgs e)
{
ValidatePath(); /* Disables/enables buttons and updates brushes based on validation. Also working */
}
private void ValidatePath() {/* */}
}
Like I mentioned earlier, the browse button works fine. I'm trying to figure out however, how I can get this to work if I type a directory alongside it. Because if I type something in the textbox, that would mean that inside of the InstallDir_TextChanged() function I would have to set viewModel.Directory, but since I have the INotifyPropertyChanged attached to this ViewModel, this function would get called recursively.
I tried doing the validation stuff within the viewmodel, but I couldn't figure out how to update the brushes/buttons in MainWindow if I did this. (Still relatively new to C# so I haven't learned the ins and outs yet. This is the first WPF tool I've been making from scratch, so just a disclaimer).
Would anyone have any ideas (or logic) I can approach to try and accomplish this? If there's any further clarification needed, that's not an issue. I don't need an exact definitive answer. Maybe some advice that could point me in the correct direction would definitely suffice. I don't have a problem trying to figure stuff out.
My goal
I am working on a project in C# using Visual Studio 2013. The project is one that I intend to contain a lot of pages. These pages are all linked together using buttons. My problem is that I cannot come up with an efficient and elegant solution for this.
My attempts
So far I have came up with two potenial solutions to my problem. First I added extra forms and then on button press I hid the current form and displayed the new form, like so:
Form2 frm = new Form2();
frm.Show();`
Form1.Hide();
While this does work, I have two problems with it.
My project will end up with hundreds of forms
The transition between forms looks sloppy. I am aiming for a browser like transition by where all navigation occurs on one window, without opening and closing others.
The second potential solution I tried incorporated the use of Panels. So I essentially created each page on a different Panel. Then the appropriate panel was shown upon a button press and the rest were hidden. Like this:
private void button1_Click(object sender, EventArgs e)
{
mainMenuPanel.Hide();
submenuPanel1.Show();
submenuPanel2.Hide();
submenuPanel3.Hide();
submenuPanel4.Hide();
}
This is exactly what I was looking for however my issue with it is that managing the vast amount of panels quickly became a nightmare. Editing the controls on a Panel that was hidden behind 9 other Panels and as the number of panels in my project was only going to grow - this does not seem like the ideal solution in its current form.
In my head I thought there maybe an option in Visual Studio 2013 that allows me to 'hide' the Panels I am not using on the form, or drag them off the form temporarily. Is that an option in Visual Studio.
If not do any of you know a more efficient and manageable way of achieving this?
Thanks in advance.
If you are stuck using WinForms, your best bet is probably using UserControls. you can actually extend the UserControl class out to be a "page" ie: UserControlPage. This makes the form much simpler in function, but you will need to do some finicky work with handling events /passing data if the controls need to talk to each other.
if you aren't nailed into using Winforms, WPF supports all of this natively, and has wonderful tools for building all the pages you would need, and storing/populating your data, and propagating events.
If you want to have single form with changing content, and you don't want to mess up with panels in one form, then solution is user controls. You will be able to create them dynamically and add to form controls. Also there is no mess, because your form will be very simple - you can have single 'placeholder' control which will be used to dock user control which is currently displayed (e.g. panel control):
private void ShowContent(Control content)
{
placeHolderPanel.Controls.Clear(); // clear current content
placeHolderPanel.Controls.Add(content); // add new
content.Dock = DockStyle.Fill; // fill placeholder area
}
Usage:
private void button1_Click(object sender, EventArgs e)
{
ShowContent(new FooUserControl());
}
You could subclass the Panel class and create as many of those custom panels as needed, then they would be inserted on your Main Form, and managed as you described.
The advantage is that you would be able to individually edit them as a separate user control.
The drawback is that you lose direct event handling of controls on those panels from the main form. You can still define your own events on those panels and delegate the individual control events.
There's always a trade-off somewhere.
Cheers
I'm new into WPF and have a problem I can't seem to find a solution for.
I'm writing a G19 (Keyboard) applet. This Keyboard has a 320x240 display attached, which you can access with C#.
I'm using WPF for this, because I don't need to do any GDI drawing anymore and use the normal controls instead.
So. It works as I wish. Everything draws properly except one UserControl. I have downloaded this control -> http://marqueedriproll.codeplex.com/
In the designer, the control works, the Loaded event get's fired and the animation is good.
When I run my application, I just see the label and the text. The animation does not work, and the Loaded event does not fire anymore.
Any help is appreciated.
The main function is my wrapper. The wrapper is already a Usercontrol and displays plugins which are switchable. This wrapper has the Frame Control(Wrapper1). I replace the content of this frame every time I switch the plugin.
public void SetPlugin(IPlugin plugin)
{
if (this.MainPlugin != null)
{
this.MainPlugin.OnHide();
((UserControl)this.MainPlugin).Visibility = System.Windows.Visibility.Hidden;
}
this.MainPlugin = plugin;
((UserControl)this.MainPlugin).Visibility = System.Windows.Visibility.Visible;
this.MainPlugin.OnShow();
this.Wrapper1.Content = this.MainPlugin;
}
I think it's the right approach to handle a plugin system that way. The plugin get's drawed on my keyboard.
What I don't understand is why the usercontrol only works in the designer view and not in the running application.
The basic code of the scrolling label is so:
public MarqueeText()
{
this.Loaded += new RoutedEventHandler(MarqueeText_Loaded);
InitializeComponent();
canMain.Height = this.Height;
canMain.Width = this.Width;
}
void MarqueeText_Loaded(object sender, RoutedEventArgs e)
{
StartMarqueeing(_marqueeType);
}
I don't see a reason why it doesn't work. Actually Ive always found a way to fix a problem but this time I see nothing.
Thanks in advance. Your help is really required today.
Have a great saturday! :)
I am guessing you are rendering to a bitmap target, rather than onscreen. If you are using RenderTargetBitmap, you have a couple of responsibilities. You need to set both a presentation source, and make sure you run events on the dispatcher.
Normally, App.xaml or Application.Run does this for you, but if you are not using a Window, you are on your own.
See this related question for details.
I am embedding usercontrols in a panel and using DevExpress Navigator control to navigate from one to the other. What I am concered about is any implications to this method?
I would give examples of what I am concerned about but then I wouldn't need to ask this question...
I have a primary form, ShellForm that has a docked Navigator Control on the left and a docked Panel Control for the rest. I then dock a User Control, say ucSearchPage, in the Panel when the link is clicked.
public partial class ShellForm : XtraForm
{
private ucSearch searchPage = new ucSearch();
private ucEnrollments enrollmentPage = new ucEnrollments();
private ucGeneral generalInfoPage = new ucGeneral();
private ucContacts contactPage = new ucContacts();
public ShellForm()
{
InitializeComponent();
}
private void ShellForm_Load(object sender, EventArgs e)
{
this.pnlShellHost.DockControl(this.searchPage);
}
private void navSearch_LinkClicked(object sender, DevExpress.XtraNavBar.NavBarLinkEventArgs e)
{
this.pnlShellHost.DockControl(this.searchPage);
}
private void navEnrollment_LinkClicked(object sender, DevExpress.XtraNavBar.NavBarLinkEventArgs e)
{
this.pnlShellHost.DockControl(this.enrollmentPage);
}
The code for DockControl() is as follows -->
public static void DockControl(this Control control, UserControl userControl)
{
userControl.Dock = DockStyle.Fill;
control.Controls.Clear();
control.Controls.Add(userControl);
}
Are there any implications to this approach? Is it just plan stupid?
I am one of those programmers that had to learn to run before walking so I have a tendency to fall flat on my face!
There will be about 30 User Controls in all.
Any insight is welcomed and appreciated!
IMO it is not a bad idea at all to embed user controls. In fact, that is exactly what they were meant for. Because every control inherits from the same base class you can build a tree structure of controls using the Composite pattern. This will allow you to create just about anything you would like.
If you think of a basic web page, this is actually what you are doing anyways: placing one element in another, or embedding them. You can have multiple divs in other divs etc. This is essentially what you are doing when you embed user controls as the user controls render to basic HTML.
Hope this helps.
EDIT: To address the concerns in your comment... I don't think you will have a problem from the data entry standpoint. The reason why is because you are using different user controls for your enrollment control and search control. I'm assuming you are overriding the OnLoad event in each of those user controls right? What happens on post back is that the Search's OnLoad will be hit if the search control was loaded, while the enrollment's OnLoad will be hit if that was loaded.
Because of the polymorphism of the user controls, you can handle the data for those controls separately.