How to add a button outside datatemplate in itemscontrol - wpf

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>

Related

WPF DataTemplate and binding with TextBlock

<Window.Resources>
<DataTemplate x:Key="pointGroupTemplate" DataType="{x:Type ac:PointGroup}">
<TextBlock Text="{Binding Name}" />
</DataTemplate>
<DataTemplate x:Key="tt2" DataType="{x:Type ac:PointGroup}">
<TextBlock Text="{Binding PointsCount}"/>
</DataTemplate>
</Window.Resources>
the first template works well with:
<ComboBox x:Name="comboBox1" ItemTemplate="{StaticResource pointGroupTemplate}" SelectionChanged="ComboBox1_SelectionChanged"
Height="25" Margin="0,5,0,5">
but i want to use the second one in a textblock
<TextBlock x:Name="textBlock1" Text="{Binding ElementName=comboBox1 ,Path=SelectedItem ?????}"/>
anyhelp.
In order to have a DataTemplate applied, you need a ContentPresenter or ContentControl:
<ContentControl ContentTemplate="{StaticResource tt2}"
Content="{Binding SelectedItem, ElementName=comboBox1}"/>

Length of ListView relative to the size of window(Visual Studio extension)

I have developed one Visual Studio extension. The problem that I am encountering is the ListView as marked in the snapshot should not go below a certain point. The result here is correct:. The ListView uses as much space as required to display 10 items. But when I shrink the window(Visual Studio extension) as shown here:, the Next button is over the ListView & Previous button is under the ListView. The expected result should be that in the second snapshot, the ListView should not go below 10 pixel above the Next & Previous buttons (as marked by green line). It already has scroll bar. How to solve this problem? Kindly ask for more information if needed.
Update : Here is the XAML as asked in comment:
<UserControl x:Class="A.B.C"
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:A.B.SE.Manager"
mc:Ignorable="d"
DataContextChanged="UserControl_DataContextChanged" >
<Grid>
<ListView Margin="10,195,10,10" Name="questionListView" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ItemsSource="{Binding Path=SEQuestions}" VerticalAlignment="Top">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<Expander Cursor="Hand">
<Expander.Header>
<TextBlock TextWrapping="Wrap" FontSize="16" Foreground="#FF81B9F1">
<Run Text="{Binding Path=title}"/>
</TextBlock>
</Expander.Header>
<StackPanel>
<TextBlock Text="{Binding Path=body_markdown}" Foreground="#FFB2AAAA" TextWrapping="Wrap"/>
<WrapPanel>
<Expander>
<Expander.Header>
<TextBlock>
<Run Text="{Binding Path=comment_count, StringFormat='\{0} comment'}"/>
</TextBlock>
</Expander.Header>
<ListView Name="commentListView" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ItemsSource="{Binding Path=comments}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock TextWrapping="Wrap" Text="{Binding Path=body_markdown}"/>
<Separator/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Expander>
<Expander>
<Expander.Header>
<TextBlock>
<Run Text="{Binding Path=answer_count, StringFormat='\{0} answer'}"/>
</TextBlock>
</Expander.Header>
<ListView Name="answerListView" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ItemsSource="{Binding Path=answers}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock TextWrapping="Wrap" Text="{Binding Path=body_markdown}"/>
<Separator/>
<Expander>
<Expander.Header>
<TextBlock>
<Run Text="{Binding Path=comment_count, StringFormat='\{0} comments'}"/>
</TextBlock>
</Expander.Header>
<ListView Name="commentsOnAnswerListView" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ItemsSource="{Binding Path=comments}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock TextWrapping="Wrap" Text="{Binding Path=body_markdown}"/>
<Separator/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Expander>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Expander>
</WrapPanel>
<TextBlock Text="{Binding Path=last_activity_date, StringFormat='Last activity at {0}'}"/>
</StackPanel>
</Expander>
<Separator/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Content="Next" Margin="10,740,10,10" HorizontalAlignment="Left" VerticalAlignment="Top" Width="60" Click="nextButtonClick"/>
<Button Content="Previous" Margin="200,740,10,10" HorizontalAlignment="Right" VerticalAlignment="Top" Width="60" Click="previousButtonClick"/>
</Grid>
</UserControl>

How can I specify multiple DataTemplate in windows.resources for use by a ContentControl

How can I specify multiple DataTemplate in windows.resources for use by a ContentControl?
My code:
<Window.Resources>
<DataTemplate x:Key="CustomerTemplate" DataType="{x:Type local:Customer}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding FirstName}"/>
<TextBlock Text=" ("/>
<TextBlock Text="{Binding Occupation}"/>
<TextBlock Text=")"/>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="PersonTemplate" DataType="{x:Type local:Person}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding FirstName}"/>
<TextBlock Text=" - "/>
<TextBlock Text="{Binding LastName}"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
Thank you so much!
Use DataTemplateSelector to return the Datatemplate you want to be applied..
<ContentControl ContentTemplateSelector="{StaticResource MyTemplateSelector}"/>
here MYtemplateselector is DataTemplateSelector, in Select() method of selector you can check for the property bound to contentcontrol and return the corresponding Datatemplate.
Thanks
Remove x:Key from DataTemplate and try this:
<ContentControl Name="CustomerContentControl">
<local:Customer />
</ContentControl>
<ContentControl Name="PersonContentControl">
<local:Person />
</ContentControl>
In this article, Josh Smith show, how to get access the elements that are in the DataTemplate:
How to use FindName with a ContentControl

How to get ContentControl to resolve DataTemplate

Why does this not resolve the datatemplate?
<Window.Resources>
<DataTemplate DataType="system:DateTime" >
<Grid Background="Aqua">
<TextBlock Text="{Binding Day}"></TextBlock>
</Grid>
</DataTemplate>
</Window.Resources>
<Grid>
<ContentControl Content="{x:Static system:DateTime.Now}"/>
</Grid>
Writing a TemplateSelector feels like an overkill.
DataType design suggests the presence of a directive x:Type like that:
<DataTemplate DataType="{x:Type system:DateTime}">
<Grid Background="Aqua">
<TextBlock Text="{Binding Day}" Height="30" Width="100" HorizontalAlignment="Center" />
</Grid>
</DataTemplate>
See the MSDN for more information.

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}" />

Resources