3

いくつかのGridViewColumnsを含むWPFウィンドウにListViewがあります。最初の列はチェックボックスに使用されます。残りの列は非常によく似ており、テキストブロック付きのデータテンプレートが含まれています。これらのそれぞれに単一のデータテンプレートを再利用できるようにしたいのですが、バインディングが列ごとに異なるため、これをどのように実行するかがわかりません。

以下はXAMLの例です。最初のGridViewColumnはチェックボックスです。他の2つには、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 に答える