Reputation: 1253
I have a ListView in a WPF window containing a number of GridViewColumns. The first column is used for a checkbox. The remainder of the columns are very similar, containing a datatemplate with a textblock. I would like to be able to reuse a single datatemplate for each of these, but I'm not sure how to pull this off, since the binding is different for each column.
Below is some example XAML. The first GridViewColumn is the checkbox. The other two contain examples of the DataTemplate. How can I reuse this DataTemplate across several columns that have different bindings?
<ListView
AlternationCount="2"
DataContext="{StaticResource TaskGroups}"
ItemContainerStyle="{StaticResource TaskItemStyle}"
ItemsSource="{Binding}"
SelectionMode="Single">
<ListView.View>
<GridView>
<GridViewColumn
Header="Completed"
CellTemplate="{StaticResource CompletedCellTemplate}"
/>
<GridViewColumn Header="Name">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid>
<Rectangle Name="StrikeThrough" HorizontalAlignment="Stretch" VerticalAlignment="Center"
Height="1" StrokeThickness="1" Stroke="Transparent"/>
<TextBlock Text="{Binding Path=Name}"/>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=IsCompleted}" Value="True">
<Setter TargetName="StrikeThrough" Property="Stroke" Value="Black"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Status">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid>
<Rectangle Name="StrikeThrough" HorizontalAlignment="Stretch" VerticalAlignment="Center"
Height="1" StrokeThickness="1" Stroke="Transparent"/>
<TextBlock Text="{Binding Path=StatusDescription}"/>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=IsCompleted}" Value="True">
<Setter TargetName="StrikeThrough" Property="Stroke" Value="Black"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
Upvotes: 3
Views: 1886
Reputation: 3227
The only difference in those templates is the text which is displayed. So, you can create user control to reuse layout and strikethrough logic.
Moreover, there is TextBlock.TextDecoration
. It's better to use that instead of custom tricks.
Here is the example of mentioned control:
MyUserControl.xaml:
<UserControl x:Class="WpfApplication1.MyUserControl"
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:WpfApplication1="clr-namespace:WpfApplication1" mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<TextDecoration x:Key="MyStrikeThrough" Location="Strikethrough"/>
<WpfApplication1:BoolToTextDecorationConverter x:Key="BoolToTextDecorationConverter" Decoration="{StaticResource MyStrikeThrough}" />
</UserControl.Resources>
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=Text}" TextDecorations="{Binding IsCompleted, Converter={StaticResource BoolToTextDecorationConverter}}" />
</UserControl>
MyUserControl.xaml.cs:
using System.Windows.Controls;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MyUserControl.xaml
/// </summary>
public partial class MyUserControl : UserControl
{
public string Text { get; set; }
public MyUserControl()
{
InitializeComponent();
}
}
}
And converter:
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace WpfApplication1
{
public class BoolToTextDecorationConverter : IValueConverter
{
public TextDecoration Decoration { get; set; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is bool && (bool)value)
{
return new TextDecorationCollection {Decoration};
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
Upvotes: 3