Grigor Aleksanyan
Grigor Aleksanyan

Reputation: 550

WPF: Use element multiple times in XAML

For example I have an element in some XAML view.

<TextBox x:Name="SomeName" Text="{Binding SomeText}"></TextBox>

<Grid>
    <!-- TODO: Render "SomeName" here-->
</Grid>
<Grid>
    <!-- TODO: Render "SomeName" here also-->
</Grid>

Is it possible?

For example by ContentControl or something...

Upvotes: 0

Views: 1937

Answers (3)

ASh
ASh

Reputation: 35646

as a possible solution you can define TextBox as non-shared resource. and then display that resource in different ContentControls (via Content property)

<Window>
    <Window.Resources>
        <TextBox x:Key="SomeName" Text="{Binding SomeText}" x:Shared="False"/>
    </Window.Resources>

    <Grid>
        <ContentControl Content="{StaticResource SomeName}"/>
    </Grid>
    <Grid>
        <ContentControl Content="{StaticResource SomeName}"/>
    </Grid>
</Window>

in this example two TextBoxes will be generated, both bound to SomeText

Upvotes: 0

Seb
Seb

Reputation: 660

You're right about the ContentControl idea, you just need to use it with a "DataTemplate"

<UserControl.Resources>

    <DataTemplate x:Key="SomeNameTemplate">
        <TextBox Text="{Binding}" />
    </DataTemplate>

<UserControl.Resources>

<StackPanel>
    <ContentControl Content="{Binding SomeText}" ContentTemplate="{StaticResource SomeNameTemplate}" />
    <ContentControl Content="{Binding SomeText}" ContentTemplate="{StaticResource SomeNameTemplate}" />
    <ContentControl Content="{Binding SomeText}" ContentTemplate="{StaticResource SomeNameTemplate}" />
</StackPanel>

EDIT:

The ContentControl and any control with a "Content" field can automatically select it's template by type.

// Let's define a collection item type
class Item
{
    public Item ( string text, DateTime date )
    {
        SomeText = text;
        SomeDate = date;
    }

    public string SomeText { get; private set; }
    public DateTime SomeDate { get; private set; }
}

// A simple viewmodel
class SomeViewModel : ViewModelBase
{
    public SomeViewModel ( )
    {
        Items.Add ( new Item ( "Item A", DateTime.MinValue ) );
        Items.Add ( new Item ( "Item B", DateTime.UtcNow   ) );
        Items.Add ( new Item ( "Item C", DateTime.MaxValue ) );
    }

    public ObservableCollection<Item> Items { get; }
     = new ObservableCollection<Item> ( );
}

Instead of giving it a key, we define our template by a type

<UserControl.Resources>

    <DataTemplate DataType="{x:Type local:Item}">

        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding SomeText}" />
            <DatePicker DisplayDate="{Binding SomeDate}" />
        </StackPanel>

    </DataTemplate>
</UserControl.Resources>

In both case, wpf will check the content's type and use our previous template we defined by type

<Grid>
    <ContentControl Content="{Binding Items[0]}" />

    <ItemsControl ItemsSource="{Binding Items}" />
</Grid>

Upvotes: 2

MaxB
MaxB

Reputation: 438

You can use Resources, as follows:

<Window.Resources>
    <Style TargetType="TextBlock" x:Key="myTextBlock">
        <Setter Property="Text" Value="myText"/>
    </Style>
</Window.Resources>

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>

    <TextBlock Style="{StaticResource myTextBlock}" Grid.Row="0"/>
    <TextBlock Style="{StaticResource myTextBlock}" Grid.Row="1"/>
    <TextBlock Style="{StaticResource myTextBlock}" Grid.Row="2"/>
</Grid>

Upvotes: 0

Related Questions