Custom Wizard Control in WPF to add and remove UserControls? - wpf

How best can I create a Wizard control in WPF. My tak is; first I have a Wizard Controller UserControl, that contains two buttons, i.e. Back and Next, then I have start off with two other UserControls with forms for users to fill in and click next step to the next form etc... What I woud like to know is how I could inserted this usercontrols and validate my current object before going to the next form. What can I use to get the next and previous events or is there a better solution for this?

Im still learning WPF, and am working on WinForm project atm, so sorry for any WinForm references in this.
The wizard control could contain a reference to each usercontrol the wizard will display. The wizard will add all these controls to itsself controls.add(_userControl1). Each control has its visible property set to false.
The wizard could also contain a private enum with a list of control names, i.e.
private enum CurrentControl
{
_MyControl1,
_MyControl2,
_MyControl3
}
Wizard control keeps a reference to the current displayed control CurrentControl _currentControl = CurrentControl._MyControl1; Have a UpdateDisplay() method, which based on the _currentControl will only make that one control visible.
Then when you click on Prev/next buttons, it updates the _currentControl varible based on its current value, calls UpdateDisplay() to show th enext control.
This way you have a reference to all your user controls (and thus the data they contain), and thus you can validate the content and your wizard can go back and forward through them by using the buttons on the wizard, and the logic in the wizard showing and hiding the controls.

You might be interested in the EmailClient (ViewModel) sample application of the WPF Application Framework (WAF). It shows how to create a Wizard with the Model-View-ViewModel pattern and it contains validation logic which disables the Next button when the user input is not valid.

Related

About custom control usage

I want to understand its logic and to modify. This library is refactored based on the open source library. I'm not very familiar with customization. Of course, I'll study hard.
How is it created automatically?
How is it grouped with controls, and where are properties controlled?
The Library: https://github.com/kelicto/KeLi.TreeListViewKit
How to Test: create a new form and add a TreeListView control.
Not sure i fully understand the question but:
WindowsForms comes with a UI design via Visual Studio. Users drag controls from the designer onto the target form. Each component on the form is clickable, and there is an associated Properties window; this is where values for the properties can be altered. The code in InitializeComponent, whether it be a form, or a custom control is automatically generated by the forms designer. e.g.: when you first start up there is a blank small form with no components.
Drag a textbox control from the left hand side and place it on the form. The form now contains a textbox. Click on the textbox and you can alter the properties of the textbox (name, value, width, even event handlers). Each change will alter how InitializeComponent works.
So if you wanted this custom component on your form you will need to compile the assembly it belongs and add the assembly so it can be referenced by the forms designer. Once this is done your TreeView component will be available to be dragged & dropped onto the form. Do this and you will also be able to set its properties.
Even custom components come with a designer piece; so if you were designing a component from scratch you could still drag / drop components onto that custom control and same as a form the implementation of InitializeComponent will change according to the components dropped, and the properties you set (and their location, anchoring etc which can be done on the main forms designer). I wouldn't recommend building a WindowsForms app without the designer, not that it cannot be done; ultimately it's code at the end of the day. But it's a lot more awkward to do without the visual designer component.

Changing the data in a specific area of a window, Caliburn.Micro, WPF

Here is my need. I think a user control is what I need but I am not sure if its the best or even how to use it.
What I have. My main window has a menu with a "help" menu. When you click help, a new window opens, I have a column, At the top of the left column has a drop down box of "Major Titles", a ListBox below that that populates based on the combo box selection. This will be about 25% of the window width. All this works.
When I select an item in the list box a page,contentControl or user control is displayed to the right with verticle scroll bars so the window does not need to resize, the information I display that changes based on the list box selection will have only visuals like text block, label, images. There will be no user interaction with the changeable pages Just formatted Data.
What would be the best way to approach this? Can anyone offer an easy example?
I was thinking of using a user control and change the user control based on the selected list box item.
Ok, I got this figured. After reading a lot of posts and blogs. Seems people sometimes want to make things more complicated then they actually are.
What I wanted, a permanent list box on the left 1/6 of the window. The list box contained string names for "help subjects". On the right 5/6 of the screen I added a groupbox with header and in group box I added a usercontrol. The content of the control is bound to a property called 'ActiveView'. The list box selected value property is bound to 'SelectedListItem' property.
When you change it set 'SelectedListItem' a method is called 'SetActiveControl'. SetActiveControl has a switch/case that sets like in the example:
``Case "Setup":
ActiveView = new SomeSelectionViewModel();
Break;
I have created a user control in a folder inside the Views folder called HelpControls, I also created the same folder in ViewModels. I have classes matching the user controls and everything is bound together.
Ultimately when you click the list box item, the associated ViewModel is called and in turn populates the user control on the window with the appropriate data.
I need to later look into, using one ViewModel for all the controls, I know that can be done using Cal:Model.View = ViewModel name. In the xaml of the control. I'm just not sure how to call the appropriate user control view when an item is selected. Either way this would become a view first design and I thought I read, Caliburn. Micro was intended as a ViewModel first design.

Winforms Databinding and multiple Forms

i have a main window that contains multiple UserControls, arranged as tab pages and tab groups (much like Visual Studio allows to have two or more editors visible at the same time).
I also have the possibility to open such an UserControl into a seperate floating window.
One of these UserControls contains simple form fields (e.g. text boxes). These text boxes are bounded with common databinding to an object / property. The binding mode is OnValidation (not on OnPropertyChanged).
When I switch the focus from this User Control inside the main window into another UserControl in the Main windows, the validation is automatically performed and the databinding is finised / the changed text will be set on the model object / property that is bounded to that text field.
But if I switch the focus to an UserControl which resides in another (floating) window, the databinding is not finished since no validation is performed.
I know that I can handle this manually by triggering ValidateChildren etc, but this seems to my the wrong way / is ugly.
Is there a "correct" / clean way to solve this issue? I want that the validation is performed as soon as the UserControl loses its focus or the window gets deactivated.
One information: On of my UserControls contains a TreeControl. If I edit a tree node label, and when I switch the focus to another (foating) window, the label edit is finished automatically. I want the corresponding behaviour for usual form fields regarding binding...
Thanks for help!
There is no automatic way to do this. From the point of view of the control, it still has the focus (if you click the title bar or Alt-tab back to the main window, you will notice that the focus remains in the same control). Its just that the form the control is on is not active. If you want it to save changes when your form is deactivated, you must manually trigger it. The best way to do that is probably to override the OnDeactivate method of the form.
protected override void OnDeactivate(EventArgs e)
{
base.OnDeactivate(e);
this.ValidateChildren();
}

Dynamic child user controls MVVM

I have a user control on a page and I'd like to load another custom user control within it's grid. However I want the user control type to be dynamic - e.g selecting "Calculator" from a drop down list would display my custom calculator control and selecting "Currency Converter" would load my currency converter. Can anybody help?
By the way I am trying to stick to MVVM.
Thanks in advance.
One way is to define multiple DataTemplates one for each child. As user selects the option set the corresponding ViewModel to a ContentControl's DataContext present in parent view and framework will pick the corresponding view for you.
John Papa has written a great blog post on exactly how to do this here.
The basic strategy is to instantiate a new instance of a class that derives from UserControl once selected from the drop down.
In other words, the SelectionChanged event of the drop down list could be handled and a new UserControl object created based on the selected item.

Re-using Buttons in WPF

I have a bunch of different objects that are commonly edited in the same TabControl using different DataTemplates, but I want each DataTemplate to have a common look and feel with Ok and Cancel buttons at the bottom right of each tab that will close the tab or save the content and then close the currently selected tab. What's the best way to place buttons on each tab ? Is there a way to do it without copying and pasting the buttons and stack panel across all of my data templates ?
Sure, you can create your own OkCancelSaveControl. In WPF, creating a "user control" is much easier than it sounds. Here is a tutorial. In a nutshell, you
create a new user control,
create properties in the user control that give the your control the information it needs to perform its duties (e.g. the tab that it's supposed to close or the data object that it's supposed to save),
if necessary, create events that the user control raises (OkClick), in case some tab requires special treatment.
I would make a custom control, lets call it MyCoolTabItem, that inherits from the TabItem class, and just throw your buttons into the control. Then just add a MyCoolTabItem instead of a TabItem to all of your TabControls and it will have all of your buttons on it.
You could make a base view class that held those buttons. Views that needed the buttons would inherit them and common functionality.

Resources