Dynamic WPF GUI Elements

In WinForms, it was relatively easy to swap Panels at runtime for other panels. In WPF, this looks pretty complicated (especially from XAML).

Can anyone give clear guidance on how to “best practice” for replacing gui elements at runtime (think of pages in a wizard-like situation).

Many thanks.

+4
source share
5 answers

The basic concepts of WinFomrs and WPF are different. WPF is not recommended to play directly with UIElements (Controls). Use DataBinding / DataContexts and just work with the data and then the user interface will function accordingly. This concept applies to the MVVM WPF template. You can look at some MVVM samples and try it out before doing more complex WPF projects.

A simple example. Suppose you need to dynamically use multiple items in a ListBox. A typical winform way for this is to create items and add directly to the ListBox. But in WPF, you create an ObservableCollection<Customer> and bind this to a ListBox.ItemsSource. then define a DataTemplate for the client data type, this will allow the WPF system to understand how the client collection is displayed in the application. Therefore, when you add a new client instance to the collection, your ListBox will be magically updated with another element. Seems a pretty straightforward and very loosely coupled way of Data and View? Best regards in learning WPF. -

http://www.bing.com/search?q=WPF+MVVM

Thus, a high level of clue to your question is to make the presentation appropriate for the data and when the data / properties change, WPF will take care of changing the panels / controls. Thus, it is really simpler than WinForms when you approach data perception and presentation.

+1
source

This can be approached in XAML using datatemplates and / or triggers. For example, if each page in your wizard was presented in the base model as a separate class or object, you can use one of the following two parameters ... Both use ContentControl, which is an ideal control when the content changes significantly between different representations of the same data.

Please note that bindings are intended as examples of pseudocode to convey intent!

Based on a DataTemplate using different classes for each page:

 <Grid> <Grid.Resources> <DataTemplate DataType="{x:Type WizardPageOne}"> <!-- page 1 layout here --> </DataTemplate> <DataTemplate DataType="{x:Type WizardPageTwo}"> <!-- page 2 layout here --> </DataTemplate> <!-- ... etc --> </Grid.Resources> <ContentControl Content="{Binding CurrentPageModel, Source=Wizardmodel}" /> </Grid> 

Or Based on a trigger using a property that indicates the current page:

 <ContentControl Content="{Binding WizardModel}"> <ContentControl.Style> <Style> <Style.Triggers> <DataTrigger Binding="{Binding CurrentPageIndex} Value="1"> <Setter Property="Template"> <Setter.Value> <ControlTemplate> <!-- page 1 layout here --> </ControlTemplate> </Setter.Value> </Setter> </DataTrigger> <DataTrigger Binding="{Binding CurrentPageIndex} Value="2"> <Setter Property="Template"> <Setter.Value> <ControlTemplate> <!-- page 2 layout here --> </ControlTemplate> </Setter.Value> </Setter> </DataTrigger> <!-- .... etc --> </Style.Triggers> </Style> </ContentControl.Style> </ContentControl> 

Both options will only load the control for each page, as required, so you do not have all the controls loaded but hidden in the window.

+5
source

A couple of options come to mind. If you create your components as UserControls and use data binding, then you should be able to do everything you need with minimal fuss.

There is only one option - load each component into the parent container (grid, canvas, whatever) using Visibility = "Collapsed", and then show and hide them as needed. This has the advantage that you can do this declaratively in XAML.

Another option is to load the components as needed, therefore in the button's event handler or in another user interface element. In this case, you probably want to remove the current display item from the Children collection of your host component, and then instantiate your next control, set the DataContext (which is why binding is important) and add it to the Children collection.

( disclaimer ): this is based on my experience, mainly what you ask for in Silverlight 3.0, so there may be some WPF quirks that I don't know about).

0
source

MVVM suggestions are good here. But if you are developing a page-oriented user interface that should be navigation, you can also use Structured Navigation .

0
source

I had no idea if this was considered good practice, but what we did in one of our projects is pretty simple. We identified the panels that were on top of each other, and simply set the visibility to be both hidden and visible when needed.

0
source

Source: https://habr.com/ru/post/1303165/


All Articles