Binding to DataTemplate - wpf

I have a button template:
<DataTemplate x:Key="TemplateTest">
<Button Margin="10" BorderThickness="2" Content="{Binding Text}" />
</DataTemplate>
I want to create a textbox and a button whose content is the same as the textbox's text.
<TextBox x:Name="TextBox" Margin="10">TextBox</TextBox>
<ContentControl DataContext="{Binding ElementName=TextBox}"
ContentTemplate="{StaticResource ResourceKey=TemplateTest}" />
But I don't get anything on the button in this way.

#DanPuzey's one still did not work for me in VS2012. Not sure why it did in Kaxaml
This did:
<TextBox x:Name="TextBox"
Margin="10"
Text="Hello World" />
<ContentControl Content="{Binding ElementName=TextBox,
Path=.}"
ContentTemplate="{StaticResource TemplateTest}" />
and
<DataTemplate x:Key="TemplateTest">
<Button Height="100"
Margin="10"
BorderThickness="2"
Content="{Binding Text}" />
</DataTemplate>

This is failing, quite simply, because you aren't setting the content of your content control: setting the DataContext doesn't change anything. Try this:
<ContentControl Content="{Binding ElementName=TextBox}" ContentTemplate="{StaticResource ResourceKey=TemplateTest}" />
The above worked for me in Kaxaml, but if it's not working for you then I'd suggest you try this instead, which explicitly binds to the text of the textbox:
<ContentControl Content="{Binding Text, ElementName=TextBox}" ContentTemplate="{StaticResource ResourceKey=TemplateTest}" />

first you should set the content of your contentControl to be binded to the text
<TextBox x:Name="TextBox" Margin="10">TextBox</TextBox>
<ContentControl Content="{Binding ElementName=TextBox,Path=Text}"
ContentTemplate="{StaticResource ResourceKey=TemplateTest}" />
now you need change the binding of the button:
<DataTemplate x:Key="TemplateTest">
<Button Margin="10" BorderThickness="2" Content="{Binding}" />
</DataTemplate>

I am not sure if {Binding ElementName=TextBox} sets the default Binding.Path.
You might try setting the Path to . : DataContext="{Binding ElementName=TextBox, Path=.}"
Or you can bind directly the Text property of your element:
<TextBox x:Name="TextBox" Margin="10">TextBox</TextBox>
<ContentControl DataContext="{Binding Text, ElementName=TextBox}"
ContentTemplate="{StaticResource ResourceKey=TemplateTest}" />
and
<DataTemplate x:Key="TemplateTest">
<Button Margin="10" BorderThickness="2" Content="{Binding}" />
</DataTemplate>

Related

How to add a button outside datatemplate in itemscontrol

I have created a WPF app.In that I have a Datatemplate as follows
<DataTemplate x:Key="ItemTemplate">
<StackPanel>
<TextBlock Text="item"/>
<TextBlock Text="{Binding Number}"/>
</StackPanel>
</DataTemplate>
I have an ItemsControl like this
<ItemsControl ItemsSource="{Binding Items}"
Grid.Column="1"
Grid.Row="3"
ItemTemplate="{StaticResource ItemTemplateWithButton}" />
where I need a itemtemplate like this
<DataTemplate x:Key="ItemTemplateWithButton">
<StackPanel>
<StackPanel>
<TextBlock Text="item"/>
<TextBlock Text="{Binding Number}"/>
</StackPanel>
<StackPanel>
<Button>
<StackPanel>
<TextBlock Text="item"/>
<TextBlock Text="{Binding Number}"/>
</StackPanel>
</Button>
</StackPanel>
</StackPanel>
</DataTemplate>
Is there any possibility of reusing the datatemplate in the new itemscontrol?
You can use ContentControl too
<DataTemplate x:Key="ItemTemplate">
<StackPanel>
<TextBlock Text="item"/>
<TextBlock Text="{Binding Number}"/>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="ItemTemplateWithButton">
<StackPanel>
<ContentControl ContentTemplate="{StaticResource ItemTemplate}" />
<Button>
<ContentControl ContentTemplate="{StaticResource ItemTemplate}" />
</Button>
</StackPanel>
</DataTemplate>
What I understand by reading this answer and what Liero mentioned in the comments is it's possible to reuse a DataTemplate by using either ContentPresenter or ContentControl. However:
ContentPresenter is more lightweight.
ContentPresenter is designed to be used inside control templates.
ContnetPresenter is designed to be used as-is while ContentControl is designed to be extended (inherited from).
As a result, here is a solution based on what you asked:
<DataTemplate x:Key="ItemTemplate">
<StackPanel>
<TextBlock Text="item"/>
<TextBlock Text="{Binding Number}"/>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="ItemTemplateWithButton">
<StackPanel>
<ContentPresenter ContentTemplate="{StaticResource ItemTemplate}"/>
<StackPanel>
<Button Content="{Binding}" ContentTemplate="{StaticResource ItemTemplate}" />
</StackPanel>
</StackPanel>
</DataTemplate>
You could create a UserControl to hold the xaml you want to reuse:
<UserControl x:Class="StackOverflow.SharedControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<StackPanel>
<TextBlock Text="item">
</TextBlock>
<TextBlock Text="{Binding Number}"></TextBlock>
</StackPanel>
</Grid>
</UserControl>
Then use this UserControl in both templates.
<DataTemplate x:Key="ItemTemplate">
<controls:SharedControl/>
</DataTemplate>
<DataTemplate x:Key="ItemTemplateWithButton">
<StackPanel>
<controls:SharedControl/>
<StackPanel>
<Button>
<StackPanel>
<TextBlock Text="item">
</TextBlock>
<TextBlock Text="{Binding Number}"></TextBlock>
</StackPanel>
</Button>
</StackPanel>
</StackPanel>
</DataTemplate>

Caliburn unable to load usercontrol as ActiveView inside Telerik's RadPane

I have recently moved ContentControl on the View(xaml) inside a telerik RadPane like so:
<telerik:RadDocking.DocumentHost>
<telerik:RadSplitContainer Visibility="{Binding UserControlVisible}">
<telerik:RadPaneGroup>
<telerik:RadPane CanUserClose="False" Header="{Binding Operation}">
<ContentControl x:Name="ActiveItem" Margin="10" VerticalAlignment="Top" />
</telerik:RadPane>
</telerik:RadPaneGroup>
</telerik:RadSplitContainer>
</telerik:RadDocking.DocumentHost>
Since, I have done this my UserControls are not injected as the Content inside ContentControl. I have tried to explicitly bind Content Property on ContentControl to ActiveItem but that says, unable to find the associated view.
Any help will be much appreciated.
try to add a datatemplate to the current content:
<DataTemplate>
<ContentControl cal:View.Model="{Binding}" />
</DataTemplate>
Where cal is:
xmlns:cal="http://www.caliburnproject.org"
and bind the active item explicitly.
Now it looks like
<telerik:RadDocking.DocumentHost>
<telerik:RadSplitContainer Visibility="{Binding UserControlVisible}">
<telerik:RadPaneGroup>
<telerik:RadPane CanUserClose="False" Header="{Binding Operation}">
<ContentControl x:Name="ActiveItem" Margin="10" VerticalAlignment="Top" Content="{Binding ActiveItem}">
<ContentControl.ContentTemplate>
<DataTemplate>
<ContentControl cal:View.Model="{Binding}" />
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
</telerik:RadPane>
</telerik:RadPaneGroup>
</telerik:RadSplitContainer>
</telerik:RadDocking.DocumentHost>

bind the selected item template to another control template

I got a listbox with listing down item, each item is stackpanel with an icon and description text.
<ListBox x:Name="lstSlectionTools"
SelectedIndex="2"
SelectionChanged="ListBox1_SelectionChanged">
<StackPanel Orientation="Horizontal" >
<ContentControl Template="{StaticResource Icon1}"/>
<TextBlock Margin="3,0,0,0" Text="Item1" />
</StackPanel>
<StackPanel Orientation="Horizontal" >
<ContentControl Template="{StaticResource Icon2}"/>
<TextBlock Margin="3,0,0,0" Text="Item2" />
</StackPanel>
<StackPanel Orientation="Horizontal" >
<ContentControl Template="{StaticResource Icon13}"/>
<TextBlock Margin="3,0,0,0" Text="Item3" />
</StackPanel>
<StackPanel Orientation="Horizontal" >
<ContentControl Template="{StaticResource Icon4}"/>
<TextBlock Margin="3,0,0,0" Text="Item4" />
</StackPanel>
</ListBox>
I want to show the selected item icon something like:
<ContentControl x:Name="selectTool"
Template="{Binding SelectedItem.Template, ElementName=lstSlectionTools}"" />
I am unable to figure out how to bind selected item (i.e. stackpanel first child's template to the selectTool's template.
The Binding.Path in this case would be SelectedItem.Children[0].Template.

How to reuse contents in wpf/mvvm

I have a UI that displays a pattern of "first name/last name". So I thought I would reuse the same template. But I am facing some issues getting the binding right.
Note:-
PrimaryContactDataContext is nothing but a class, with a property named "value" which implements the *INotifyPropertyChanged" interface.
<StackPanel>
<ContentControl DataContext="{Binding Path=PrimaryContactDataContext.Value,Mode=TwoWay}" ContentTemplate="{StaticResource PersonalDetailsTemplate}" />
</StackPanel>
// See the Reusable template below
<UserControl.Resources>
<DataTemplate x:Key="PersonalDetailsTemplate" >
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Width="30" Text="Name"></TextBlock>
<TextBox Width="110" Text="{Binding LastName}" IsReadOnly="True"></TextBox>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Width="30" Text="Title"></TextBlock>
<TextBox Width="110" Text="{Binding firstName}" IsReadOnly="True"></TextBox>
</StackPanel>
</StackPanel>
</DataTemplate>
</UserControl.Resources>
Set the Content of the ContentControl, not its DataContext:
<ContentControl Content="{Binding Path=PrimaryContactDataContext.Value,Mode=TwoWay}" ContentTemplate="{StaticResource PersonalDetailsTemplate}" />

WPF : InputBindings on a StackPanel

I want to put a command on a ListBoxItem. The ListBoxItem use a DataTemplate composed of a StackPanel (containing an Image and a TextBlock, both using Binding). I want that the doubleclick on that ListBoxItem fire the command.
I have tried this :
<DataTemplate>
<StackPanel>
<StackPanel.Resources>
<CommonUI:CommandReference x:Key="DoubleClickCommand" Command="{Binding Path=DefaultCommand}" />
</StackPanel.Resources>
<StackPanel.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{StaticResource DoubleClickCommand}" />
</StackPanel.InputBindings>
<Image Source="{Binding Path=Thumbnail, IsAsync=True}" IsHitTestVisible="False"/>
<TextBlock Text="{Binding Path=Name}" IsHitTestVisible="False">
</StackPanel>
</DataTemplate>
I have also tried to put the Command Resources on a StackPanel containing this StackPanel, without any change.
I am certain of my binding because when I put the InputBindings part on the TextBlock, it works.
Thanks
Try handling the event in the ListBox instead of the StackPanel:
<ListBox>
<ListBox.Resources>
<CommonUI:CommandReference x:Key="DoubleClickCommand" Command="{Binding Path=DefaultCommand}" />
</ListBox.Resources>
<ListBox.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{StaticResource DoubleClickCommand}" />
</ListBox.InputBindings>
<DataTemplate>
<StackPanel>
<Image Source="{Binding Path=Thumbnail, IsAsync=True}" />
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</DataTemplate>
</ListBox>
My code finally looks like this :
<DataTemplate>
<StackPanel Orientation="Vertical">
<StackPanel.Resources>
<CommonUI:CommandReference x:Key="DoubleClickCommand" Command="{Binding Path=DefaultCommand}" />
</StackPanel.Resources>
<StackPanel.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{StaticResource DoubleClickCommand}" />
</StackPanel.InputBindings>
<Image Source="{Binding Path=Thumbnail, IsAsync=True}" />
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</DataTemplate>
Thanks anyway, Mr Poulin.

Resources