3

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

下面是一些示例 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>
4

1 回答 1

3

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

此外,还有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();
        }
    }
}
于 2012-06-26T21:38:54.867 回答