Asperger
Asperger

Reputation: 3222

Reuse XAML in wpf?

Im new to WPF but worked with it for a month now and noticed that I might be building my UI wrong.

Here is the scenario: I have a certain container such as:

<DockPanel>
   <WrapPanel>
       ... some buttons here which are always the same.
   <WrapPanel>
   <Grid name="myGrid" ...contains some attributes>
       // Everything inside here is generated dynamically.
   <Grid>
</DockPanel>

My question is how do I deal with such a situation? I want to create some sort of template so that I can reuse it. The template should be the entire construct you see above. Right now im creating the "entire" part in code which seems kind of overkill. So I can create as many of these Dockpanels as I want but the only content that would be different is inside my grid.

I want to define a seperate XML document for this task (I call it UI module) which I can use as a template. So in code I would hope I could do something like:

Example of what im trying to achieve in pseudo code:

var panel = createNewControlFrom("/MySpecialDockPanel.xaml");
panel.Background = // Different color.
var panel.Children.FindName("myGrid");

loop start
   // Add children to panels grid.
loop end

Upvotes: 1

Views: 1758

Answers (2)

XAMlMAX
XAMlMAX

Reputation: 2363

Here is a little breakdown of the things used in WPF:
DataTemplate
This is used with Collections of certain type, so say you have a class:

class ModelItem //Implements INotifyPropertyChanged
{
    public int ID { get; set; }
    public string Name { get; set; }
}  

This would be a collection in your ViewModel:

public class MainViewModel //Implements INotifyPropertyChanged
{
    List<ModelItem> Items { get; set; }
}  

Then in your xaml you would use it like so:

<UserControl x:Class="SO_app.ForAsperger"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:SO_app"
         xmlns:vm="clr-namespace:VM;assembly=VM"//this is where we define reference to our ViewModel
         xmlns:model="clr-namespace:Model;assembly=Model"//this is where we define our model object so we know the structure for our DataTemplate
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<UserControl.DataContext>
    <vm:MainViewModel/>//Here we assign the ViewModel to our View
</UserControl.DataContext>
<UserControl.Resources>//this is where you can place Collections, Styles, Controls etc ...
    <DataTemplate x:Key="keyToReferToInXaml">
        <TextBlock Text="SomeText"/>
    </DataTemplate>
<CollectionViewSource Source="{Binding Items}" x:Key="items"/>//this is a collection of the same items but held as a StaticResource which you can then reference like <ItemsControl ItemsSource="{Binding Source={StaticResource items}}"/>
</UserControl.Resources>
<ItemsControl ItemsSource="{Binding Items}">//This is our List, you can use ListView or ListBox if this seems intimidating
    <ItemsControl.ItemTemplate>
        <DataTemplate DataType="{x:Type model:ModelItem}">//We define the target type for this DataTemplate
            <TextBlock Text="{Binding Name}"/>//Binding will pick up the properties from ModelItem and display them in a TextBlock
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Upvotes: 2

mm8
mm8

Reputation: 169420

If you simply want to be able to reuse a piece of UI you could create a UserControl and define your reusable XAML markup and any code in this one.

You could then create any number of instances of this UserControl, either programmatically:

UserControl1 uc = new UserControl1();

...or in the XAML markup of another class, for example a window:

<local:UserControl1 />

Upvotes: 3

Related Questions