My question is as follows: my app needs to show a "Hamburger" menu in the left side, while the content right of it changes depending on the context. My initial idea was to implement it with Frames inside different Pages. I learned that the Frame itself is a reference to rootFrame so there's really no need for nested Frames to get navigation going.
However, to get the Hamburger menu on all Pages I would need to include them somehow. Is there a possibility to avoid duplicating the XAML code in every Page?
Looking into this I found UserControl. The docs are a bit hard to understand for me. Say I implemented a UserControl in XAML and named a Button in it via x:Name="HamburgerButton". Then, in myMainPage` I put something like this:
<Grid x:Name="MyGrid">
<controls:MyControl />
</Grid>
The Button in the UserControl XAML has a Click event in the code behind. How do I extend / customize the implementation of it in the MainPage that uses it? I guess I don't understand the relationships between them. Also the ContentPresenter is over my head at this moment.
You don't need the ContentPresenter. That's for when you create your own templates. Your MainView should contain your Menu buttons and a ContentControl. When a user clicks one of the buttons, you exchange the Content property of the ContentControl: For each menu item you can create an extra UserControl, one of which is always set to the ContentControl. For example, when the user clicks "Menu X" then you set the Content property of your ContentControl to UserControlX that contains all the context-related things. When the user clicks "Button Y" ... you get the idea.
You can do all this from the code-behind file of your main view. In the long run, you'll probably want to look into the MVVM pattern and bind your ContentPresenter to a property of your MainView's view model - and your buttons potentially to ICommands. But it will also work via the code-behind method.
Related
I have a WPF, MVVM program whose MainWindow is separated into a ListBox sidebar and a main part with a ContentControl. I want to create a functionality that will populate the ListBox with a button for each view that I have in my project and set its command such that clicking it will set the content of the ContentControl to the associated view automatically, i.e. so that I don't have to manually enter code when adding a new view. Something like iterate through all view files or something like that.
EDIT:
Perhaps I'm AGAIN not clear enough.
What I have and can do - type like a monkey "new Button, yadda yadda" every time I add a new view to my project.
What I want - write a piece of black magic that goes something like "There are 6 views in this project, I'll just make 6 buttons each such that, when clicked, will navigate to the appropriate view, without the guy who wrote me having to write any additional line of code any time a new view is added".
How can I achieve that and is it such a good idea, to begin with?
For instructional purposes, I'll be calling your "view" class View.
Create some sort of collection object (List<View>, ObservableCollection<View>, etc.) to store all of the Views.
Assign this collection to a dependency property. I'll call it Views.
Declare a dependency property for the selected/active view. I'll call it SelectedView.
Bind ListBox.ItemsSource to Views.
Bind ListBox.SelectedItem to View.
Bind ContentControl.Content to View as well.
With the above setup, the ContentControl will display whatever View is selected in the ListBox.
I am trying to achieve this look&feel in WPF.
It basically acts like a TabControl, with the tabs on the left (vertically)
The right side of the window completely changes depending on which item you have clicked on the left "nav bar":
Oculus UI
What I did:
I started doing a Custom Control. A grid with two columns, a StackPanel in the left column in which there will be a clickable button/label for every menu entry (vertically of course). A Property MenuEntries which is a List<string>.
How do I get the control to add a "tabpage" (a grid/canvas?) programmatically for every MenuEntry the user adds at design time?
How can I achieve the behavior of the TabControl during design time, i.e. the content on the right side changes as soon as the user clicks an item on the left (in the designer/editor)? (kind of like the TabControl itself?)
Is this the right approach or would you do that completely differently?
Yes, you can use TabControl for that, just set TabStripPlacement="Left", (some more details)
The whole rest: colors, margins etc is set via styles.
Also, to save you a lot of trouble, use MVVM (with some framework for WPF) for that. Set ViewModel collection as ItemsSource for the TabControl.
Then, when you select one of the tabs, the control will display the view for the selected VM.
DO NOT set TabItems in xaml for each tab, this is wrong way to go in the long run.
I'm pretty new to WPF/XAML in C#, I saw some simple tutorials and stuff but, today I'm confused, never used to make UI there.
I need to output multiple forms which instance would look something like that:
(NB: I constructed it just in WYSIWG way, so XAML markup is total mess, it for screenshot. I cant even add table directly in grid, oh)
I got data like this for each month in schoolyear, so, depends on what class is choosen I want it to output like that (scheme)
(NB: instead of each CustomWindowInstance there I need my form from 1 st screenshot)
So, whats is best and simplies approach for that?
EDIT 1: I'll name XAML from the first screenshot, which represents controls you want to display multiple times, XAML 1, and another one, where you want to do it, XAML 2.
--
Almost ORIGINAL:
Create a separate User Control and move the content of Window tag from XAML 1 into it. Then you'll be able to show it as many times as you want by placing <yourUserControlNamespace:YourUserControlClass /> in XAML 2.
For an ability of communication with this control in XAML like <yourUserControlNamespace:YourUserControlClass Parameter="SomethingHere" /> you should implement a dependency property with name ParameterProperty (desired name of property in XAML + "Property") in YourUserControlClass.xaml.cs.
--
EDIT 2: One may also create a DataTemplate with parameter DataType={x:Type yourVMNamespace:YourVMClass} for the XAML 1's ViewModel (not View) in XAML 2's or the whole application's Resources. In that case the ViewModel class you are binding to will be represented by the DataTemplate's content itself. Later you can write <yourVMNamespace:YourVMClass /> as in the first solution.
This approach allows displaying rich representation of any items themselves, for example, in controls derived from ItemsControl, such as ListBox, all you've got to do is to bind ListBox's ItemsSource property to a collection of YourVMClass instances (or specify them in XAML by hand).
More precisely, in this case I won't call YourVMClass a ViewModel.
Actually i am trying to do a Wizard control. In which i have load 3 pages dynamically when click the next button. When i click the next button i need to store the page details so i have created a dictionary to store the usercontrol. Is there any other suggestions to store the previous page details.
There are many ways to achieve your requirements. This is what I would do, which I think is very inline with the MVVM design pattern.
Define a ViewModel class that contains all the variables that you want to collect (regardless of the partition to pages.
Add a public property named 'currentPage'.
Define the frame of the wizard. Probably a <Window> element, with a StackPanel. The Window would have a title at the top, and an area at the bottom for the 'prev' and 'next' buttons (and 'finish' if you want to).
In the main area of the StackPanel put a and bind its DataContext to the ViewModel
In the ViewModel create a Next and Pref commands (use Prism DelegateCommand, or implement your own lightweight version that derives from ICommand.
6/ Also, bind the 'Finish' button to a command, with the appropriate CanExecute logic (have you collected enough data?).
The Next and Prev 'CanExectue' logic would look at currentPage. e.g. the Prev command CanExecute will return false when currentPage is 0.
You'll have 3 different data templates, one for each page. Each data templates will present different subset of properties you want to collect at that page. Bind the UI controls to properties at the ViewModel, and have the binding mode two way.
Derive your ViewModel from INotifyPropertyChanged, and have all the setters to fire the appropriate notification. It is required for at least the currentPage property, but for the completion of the solution do it for all properties.
In the Next and Prev command Execute method will modify the currentPage property (the Setter should fire notification). The view will update automatically.
For the main area ItemControl, implement a WizardTemplateSelector derived from DataTemplateSelector. Define it as a resource, and assign the ItemControl.ContentTemplateSelector using {StaticResource} binding.
If you want to, you can also have a List control at the left side of the Window, with the Selected Item Index bound to the current page.
EDIT (Explainer): The basic idea is to have a single ViewModel, which can be Viewed in several different Data Template, depends on the current page.
I'm new to windows phone 7
I want to ask for your help in some code for:
Im developing and app which has multiple pages. Now I want to put it into a single page using some user control. For example my main page will have a company logo in a grid and a second grid which is empty. The second grid should display the UserControl in which i'll ask user to log in, after log in I want to display another UserControl for some list box and all. Trouble is I'm not getting how can I display and change user control in Page? Just like partial page in asp.net MVC.
Is there any function which gets executed every time user control is changed, like asp.net MVC has "OnActionExecuting". Can we create a UserControl as BaseUserControl and inherit each UserControl from it...is it possible????
Sorry I'm very new to this windows phone.
I'll try to give you some hints and code to manage your problems.
First. It is possible to do all what you want ;).
If you want to use only one page (possible not the best practice) you can change your Ui from code. If you have your Page, with MainGrid and two Grids, inside MainGrid. You can access each grid with the x:name property, you had set in xaml.
Example:
<Grid x:name="MainGrid">
<Grid x:Name="LogoGrid"/>
<Grid x:Name="ContentGrid"/>
</Grid>
Here you can add your userControl as following:
var control = new CustomUserControl();
ContentGrid.Children.Clear(); //maybe delete old Children
ContentGrid.Children.Add(control);
Handling the Events is also easy. Just build it into your UserControl, like a LoginButton and replace the old UserControl with the new one after ButtonClick.
You can simply change the user control by adding the user control as a child to the container Grid.
MyUserControl myusercontrol = new MyUserControl();
mygrid.Children.Add(myusercontrol);
or to remove,
mygrid.Children.RemoveAt(0); //if you have just one child control.