如何重用GridViewColumn CellTemplate并允许不同的绑定?

时间:2012-06-26 20:46:26

标签: .net wpf xaml

我在包含许多GridViewColumns的WPF窗口中有一个ListView。第一列用于复选框。列的其余部分非常相似,包含带有文本块的datatemplate。我希望能够为每一个重用单个数据模板,但我不知道如何解决这个问题,因为每个列的绑定都不同。

下面是一些示例XAML。第一个GridViewColumn是复选框。另外两个包含DataTemplate的示例。如何在具有不同绑定的多个列中重用此DataTemplate?

        <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>

1 个答案:

答案 0 :(得分:2)

这些模板的唯一区别是显示的文本。因此,您可以创建用户控件以重用布局和删除逻辑。

此外,还有TextBlock.TextDecoration。最好使用它而不是自定义技巧。

以下是上述控制的示例:

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();
        }
    }
}

转换器:

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();
        }
    }
}