【问题标题】:How can I reuse a GridViewColumn CellTemplate and allow for different bindings?如何重用 GridViewColumn CellTemplate 并允许不同的绑定?
【发布时间】:2012-06-28 06:17:44
【问题描述】:

我在一个包含许多 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>

【问题讨论】:

    标签: .net wpf xaml


    【解决方案1】:

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

    此外,还有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();
            }
        }
    }
    

    【讨论】:

    • 这绝对是一个更优雅的解决方案。唯一的缺点是当我使用用户控件时,gridviewcolumn 不再延伸到其内容的宽度。您对如何实现这一点有任何快速建议吗?
    猜你喜欢
    • 2014-05-31
    • 2011-09-15
    • 2013-01-17
    • 2017-09-14
    • 2014-11-19
    • 1970-01-01
    • 2016-09-23
    • 1970-01-01
    • 2012-10-19
    相关资源
    最近更新 更多