c# - WPF DataGrid CellTemplateSelector 项目

标签 c# wpf datagrid datatemplateselector

我有一个网格绑定(bind)到一组 VM。在为我的 DataGridTemplateColumn 使用 DataTemplateSelector 时,我将整个 VM 作为数据项获取,如何将其缩小到特定属性值(否则我必须创建 ' DataTemplateSelector' for each VM or use interfaces,两者都太麻烦了)?

Bind a property to DataTemplateSelector ,但它看起来像是一个糟糕的解决方法。

最佳答案

您可以使用 Expressions Trees在 DataTemplateSelector 的派生类中,我将其称为 PropertyTemplateSelector。这是它的代码:

public abstract class PropertyTemplateSelector : DataTemplateSelector
{
    private Delegate getPropertyValue;
    private string propertyName;
    private Type itemType;

    public string PropertyName
    {
        get
        {
            return propertyName;
        }
        set
        {
            propertyName = value;
        }
    }

    public Type ItemType
    {
        get
        {
            return itemType;
        }
        set
        {
            itemType = value;
        }
    }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (ItemType.IsInstanceOfType(item))
        {
            if (getPropertyValue == null)
            {
                System.Linq.Expressions.ParameterExpression instanceParameter =
                    System.Linq.Expressions.Expression.Parameter(item.GetType(), "p");

                System.Linq.Expressions.MemberExpression currentExpression =
                    System.Linq.Expressions.Expression.PropertyOrField(instanceParameter, PropertyName);

                System.Linq.Expressions.LambdaExpression lambdaExpression =
                    System.Linq.Expressions.Expression.Lambda(currentExpression, instanceParameter);

                getPropertyValue = lambdaExpression.Compile();
            }

            return SelectTemplateImpl(getPropertyValue.DynamicInvoke(item), container);
        }

        return base.SelectTemplate(item, container);
    }

    protected abstract DataTemplate SelectTemplateImpl(object propertyValue, DependencyObject container);
}

您可以使用自己的逻辑扩展此类,只需实现 SelectTemplateImpl 方法即可。如您所见,PropertyTemplateSelector 将项目对象缩小到特定的属性值(传递给 SelectTemplateImpl 方法)。例如,我以这种方式创建了一个 NameTemplateSelector:

public class NameTemplateSelector : PropertyTemplateSelector
{
    protected override DataTemplate SelectTemplateImpl(object propertyValue, DependencyObject container)
    {
        string name = (string)propertyValue;

        if (name != null && name.StartsWith("A", StringComparison.OrdinalIgnoreCase))
        {
            return (DataTemplate)App.Current.MainWindow.FindResource("VipName");
        }

        return (DataTemplate)App.Current.MainWindow.FindResource("NormalName");
    }
}

您可以在 XAML 中轻松使用这些模板选择器

<Window.Resources>
    <DataTemplate x:Key="NormalName">
        <TextBlock Text="{Binding Mode=OneWay, Path=Name}" Margin="3" />
    </DataTemplate>
    <DataTemplate x:Key="VipName">
        <TextBlock Text="{Binding Mode=OneWay, Path=Name}" Margin="3" Foreground="Red" FontWeight="Bold" />
    </DataTemplate>

    <DataTemplate x:Key="NormalSurname">
        <TextBlock Text="{Binding Mode=OneWay, Path=Surname}" Margin="3" />
    </DataTemplate>
    <DataTemplate x:Key="VipSurname">
        <TextBlock Text="{Binding Mode=OneWay, Path=Surname}" Margin="3" Foreground="Green" FontStyle="Italic" />
    </DataTemplate>

    <local:NameTemplateSelector x:Key="NameTemplateSelector" PropertyName="Name" ItemType="{x:Type local:Person}" />
    <local:SurnameTemplateSelector x:Key="SurnameTemplateSelector" PropertyName="Surname" ItemType="{x:Type local:Person}" />
</Window.Resources>

<Grid>
    <DataGrid ItemsSource="{Binding Path=People, Mode=OneWay}" AutoGenerateColumns="False"
                CanUserAddRows="False">
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="Name"
                                    CellTemplateSelector="{StaticResource NameTemplateSelector}" />
            <DataGridTemplateColumn Header="Surname"
                                    CellTemplateSelector="{StaticResource SurnameTemplateSelector}" />
        </DataGrid.Columns>
    </DataGrid>
</Grid>

希望对您有所帮助。

关于c# - WPF DataGrid CellTemplateSelector 项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31340606/

相关文章:

c# - pl/sql 查询和 .net 的奇怪行为

c# - 使用 SSH.NET 从 SFTP 服务器下载一个特定文件

c# - 适用于 WPF 的 Microsoft .NET 图表控件

WPF 数据网格 : copy additional rows to clipboard

c# - 列表框的SelectionChanged事件如何获取textblock文本值wp8

c# - 已加载私有(private)符号但未显示行号?

.net - 如何在旋转后而不是之前调整 WPF 元素的大小?

wpf - 如何: WPF designer binding preview with Prism

c# - 创建自定义 DataGrid 的 ItemsSource

c# - 如何在datagridview中显示图片? C#