Reputation: 3222
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
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
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