WPF dataGrid(或 ListView)通过绑定填充,不同的行模板

发布于 2024-10-26 06:05:21 字数 1702 浏览 0 评论 0原文

我有一个 WPF dataGrid,它是通过 DataBinding 填充的。该列表包含不同的列。我有两种类型的行,一种类型包含行中的所有列,另一种类型应跨越所有列的一列。

有没有一种简单的方法可以实现这一点? (也许使用 ListView 而不是 DataGrid?)

我附上了一个屏幕截图,它应该是什么样子:

在此处输入图像描述

I现在尝试使用项目模板选择器:

资源中的我的模板(这两个模板不正确,但它们仅用于测试!)

    <DataTemplate x:Key="commentTemplate">
        <TextBlock Text="{Binding}"/>
    </DataTemplate>

    <DataTemplate x:Key="normalTemplate">
        <Image Source="{Binding }" />
    </DataTemplate>

    <WPFVarTab:VarTabRowItemTemplateSelector 
        NormalRowsTemplate="{StaticResource normalTemplate}" 
        CommentRowsTemplate="{StaticResource commentTemplate}" 
        x:Key="vartabrowItemTemplateSelector" />

和我的数据网格:

<DataGrid AutoGenerateColumns="False" Margin="0,22,0,22" 
              Name="dataGrid" Grid.RowSpan="2" CanUserAddRows="True"
              RowBackground="Azure" AlternatingRowBackground="LightSteelBlue"
              ItemTemplateSelector="{StaticResource vartabrowItemTemplateSelector}" >

和我的模板选择器:

public class VarTabRowItemTemplateSelector : DataTemplateSelector 
{
    public DataTemplate NormalRowsTemplate { get; set; }
    public DataTemplate CommentRowsTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        S7VATRow vRow = item as S7VATRow;
        if (vRow == null || string.IsNullOrEmpty(vRow.Comment))
            return NormalRowsTemplate;
        return CommentRowsTemplate;
    }
}

我在 SelectTemplate 的第一行中停止,但这是从来没有打电话过!

I have a WPF dataGrid which is filled via DataBinding. This list contains different columns. I have two types of rows, one type contains all the columns in the rows, and the other should span one column over all the columns.

Is there a easy way to make this possible? (maybe use a ListView instead of a DataGrid?)

I attached a screenshot how it should look like:

enter image description here

I now tried with Item Template Selector:

My templates in the Resources (The two templates are not correct, but they are only for testing!)

    <DataTemplate x:Key="commentTemplate">
        <TextBlock Text="{Binding}"/>
    </DataTemplate>

    <DataTemplate x:Key="normalTemplate">
        <Image Source="{Binding }" />
    </DataTemplate>

    <WPFVarTab:VarTabRowItemTemplateSelector 
        NormalRowsTemplate="{StaticResource normalTemplate}" 
        CommentRowsTemplate="{StaticResource commentTemplate}" 
        x:Key="vartabrowItemTemplateSelector" />

and my Datagrid:

<DataGrid AutoGenerateColumns="False" Margin="0,22,0,22" 
              Name="dataGrid" Grid.RowSpan="2" CanUserAddRows="True"
              RowBackground="Azure" AlternatingRowBackground="LightSteelBlue"
              ItemTemplateSelector="{StaticResource vartabrowItemTemplateSelector}" >

and my Template Selector:

public class VarTabRowItemTemplateSelector : DataTemplateSelector 
{
    public DataTemplate NormalRowsTemplate { get; set; }
    public DataTemplate CommentRowsTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        S7VATRow vRow = item as S7VATRow;
        if (vRow == null || string.IsNullOrEmpty(vRow.Comment))
            return NormalRowsTemplate;
        return CommentRowsTemplate;
    }
}

I put a stop in the first row in SelectTemplate but this is never called!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

自此以后,行同陌路 2024-11-02 06:05:21

您可以使用项目模板选择器列表视图。或者使用DataGrid,也可以在那里使用。 这里是一个示例。

You can use item template selector with ListView. Or with DataGrid, it's available there, too. Here is an example.

顾北清歌寒 2024-11-02 06:05:21

使用绑定来打开和关闭数据行的可见性,如下所示。我假设您定义了列。

<DataGrid.RowDetailsTemplate>
     <DataTemplate>
     <ContentControl Style="{StaticResource CommentTemplate}" Content="{Binding Comment}" Visibility="{Binding IsCommentVisible, Converter={StaticResource BooleanToVisibilityConverter}}"/>
    </DataTemplate>
</DataGrid.RowDetailsTemplate>

检查这个
http://www.wpf-tutorial.com/datagrid-control/details -行/。如果链接损坏,下面粘贴了行和列详细信息的代码供您参考。

 <Window x:Class="WpfTutorialSamples.DataGrid_control.DataGridDetailsSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="DataGridDetailsSample" Height="200" Width="400">
        <Grid Margin="10">
                <DataGrid Name="dgUsers" AutoGenerateColumns="False">
                        <DataGrid.Columns>
                                <DataGridTextColumn Header="Name" Binding="{Binding Name}" />
                                <DataGridTextColumn Header="Birthday" Binding="{Binding Birthday}" />
                        </DataGrid.Columns>
                        <DataGrid.RowDetailsTemplate>
                                <DataTemplate>
                                        <TextBlock Text="{Binding Details}" Margin="10" />
                                </DataTemplate>
                        </DataGrid.RowDetailsTemplate>
                </DataGrid>
        </Grid>
</Window>

代码视图模型

using System;
   using System.Collections.Generic;
   using System.Windows;

   namespace WpfTutorialSamples.DataGrid_control
   {
        public partial class DataGridDetailsSample : Window
        {
                public DataGridDetailsSample()
                {
                        InitializeComponent();
                        List<User> users = new List<User>();
                        users.Add(new User() { Id = 1, Name = "John Doe", Birthday = new DateTime(1971, 7, 23) });
                        users.Add(new User() { Id = 2, Name = "Jane Doe", Birthday = new DateTime(1974, 1, 17) });
                        users.Add(new User() { Id = 3, Name = "Sammy Doe", Birthday = new DateTime(1991, 9, 2) });

                        dgUsers.ItemsSource = users;
                }
        }

        public class User
        {
                public int Id { get; set; }

                public string Name { get; set; }

                public DateTime Birthday { get; set; }

                public string Details
                {
                        get
                        {
                                return String.Format("{0} was born on {1} and this is a long description of the person.", this.Name, this.Birthday.ToLongDateString());
                        }
                }
        }
    }

Use binding to turn the visibility of datarow on and off like so. I am assuming you defined columns.

<DataGrid.RowDetailsTemplate>
     <DataTemplate>
     <ContentControl Style="{StaticResource CommentTemplate}" Content="{Binding Comment}" Visibility="{Binding IsCommentVisible, Converter={StaticResource BooleanToVisibilityConverter}}"/>
    </DataTemplate>
</DataGrid.RowDetailsTemplate>

Check this
http://www.wpf-tutorial.com/datagrid-control/details-row/. Incase the link is broken, code for row and column details for your reference is pasted below.

 <Window x:Class="WpfTutorialSamples.DataGrid_control.DataGridDetailsSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="DataGridDetailsSample" Height="200" Width="400">
        <Grid Margin="10">
                <DataGrid Name="dgUsers" AutoGenerateColumns="False">
                        <DataGrid.Columns>
                                <DataGridTextColumn Header="Name" Binding="{Binding Name}" />
                                <DataGridTextColumn Header="Birthday" Binding="{Binding Birthday}" />
                        </DataGrid.Columns>
                        <DataGrid.RowDetailsTemplate>
                                <DataTemplate>
                                        <TextBlock Text="{Binding Details}" Margin="10" />
                                </DataTemplate>
                        </DataGrid.RowDetailsTemplate>
                </DataGrid>
        </Grid>
</Window>

Code view model

using System;
   using System.Collections.Generic;
   using System.Windows;

   namespace WpfTutorialSamples.DataGrid_control
   {
        public partial class DataGridDetailsSample : Window
        {
                public DataGridDetailsSample()
                {
                        InitializeComponent();
                        List<User> users = new List<User>();
                        users.Add(new User() { Id = 1, Name = "John Doe", Birthday = new DateTime(1971, 7, 23) });
                        users.Add(new User() { Id = 2, Name = "Jane Doe", Birthday = new DateTime(1974, 1, 17) });
                        users.Add(new User() { Id = 3, Name = "Sammy Doe", Birthday = new DateTime(1991, 9, 2) });

                        dgUsers.ItemsSource = users;
                }
        }

        public class User
        {
                public int Id { get; set; }

                public string Name { get; set; }

                public DateTime Birthday { get; set; }

                public string Details
                {
                        get
                        {
                                return String.Format("{0} was born on {1} and this is a long description of the person.", this.Name, this.Birthday.ToLongDateString());
                        }
                }
        }
    }
笨死的猪 2024-11-02 06:05:21

输入图片此处描述

数据和评论的视图模型。亦作空地。

public abstract class RowViewModelBase
{
    public bool IsSpecial { get; set; }
}

public class EmptySpaceViewModel : RowViewModelBase
{
    public EmptySpaceViewModel() => IsSpecial = true;
}

public class DataViewModel : RowViewModelBase
{
    public DataViewModel(string column1, string column2)
    {
        Column1 = column1;
        Column2 = column2;
    }

    public string Column1 { get; set; }
    public string Column2 { get; set; }
}

public class CommentViewModel : RowViewModelBase
{
    public string Comment { get; }

    public CommentViewModel(string comment)
    {
        Comment = comment;
        IsSpecial = true;
    }
}

模板选择器

public class RowContentSelector : DataTemplateSelector
{
    public DataTemplate EmptyTemplate { get; set; }
    public DataTemplate CommentTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item is EmptySpaceViewModel)
            return EmptyTemplate;
        if (item is CommentViewModel)
            return CommentTemplate;
        return base.SelectTemplate(item, container);
    }
}

xaml

<Window
    ...>
    <Window.Resources>
        <DataTemplate x:Key="EmptyRow">
            <Border Height="30" />
        </DataTemplate>
        <DataTemplate x:Key="CommentTempate">
            <TextBlock Foreground="Green" Text="{Binding Comment}" />
        </DataTemplate>
        <local:RowContentSelector
            x:Key="RowContentSelector"
            CommentTemplate="{StaticResource CommentTempate}"
            EmptyTemplate="{StaticResource EmptyRow}" />
    </Window.Resources>

    <DataGrid
        AutoGenerateColumns="False"
        CanUserAddRows="False"
        ItemsSource="{Binding}"
        RowDetailsTemplateSelector="{StaticResource RowContentSelector}"
        RowDetailsVisibilityMode="Visible">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Column1}" Header="column1" />
            <DataGridTextColumn Binding="{Binding Column2}" Header="column2" />
        </DataGrid.Columns>
        <DataGrid.ItemContainerStyle>
            <Style TargetType="{x:Type DataGridRow}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type DataGridRow}">
                            <Border
                                x:Name="DGR_Border"
                                Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                SnapsToDevicePixels="True">
                                <SelectiveScrollingGrid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto" />
                                        <ColumnDefinition Width="*" />
                                    </Grid.ColumnDefinitions>

                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="*" />
                                        <RowDefinition Height="Auto" />
                                    </Grid.RowDefinitions>

                                    <DataGridCellsPresenter
                                        x:Name="cells"
                                        Grid.Column="1"
                                        ItemsPanel="{TemplateBinding ItemsPanel}"
                                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />

                                    <DataGridDetailsPresenter
                                        x:Name="details"
                                        Grid.Row="1"
                                        Grid.Column="1"
                                        SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=AreRowDetailsFrozen, Converter={x:Static DataGrid.RowDetailsScrollingConverter}, ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical}}"
                                        Visibility="{TemplateBinding DetailsVisibility}" />

                                    <DataGridRowHeader
                                        x:Name="header"
                                        Grid.RowSpan="2"
                                        SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical"
                                        Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=HeadersVisibility, Converter={x:Static DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static DataGridHeadersVisibility.Row}}" />
                                </SelectiveScrollingGrid>
                            </Border>
                            <ControlTemplate.Triggers>
                                <DataTrigger Binding="{Binding IsSpecial}" Value="True">
                                    <Setter TargetName="cells" Property="Visibility" Value="Collapsed" />
                                    <!--<Setter TargetName="header" Property="Visibility" Value="Collapsed" />-->
                                </DataTrigger>
                                <DataTrigger Binding="{Binding IsSpecial}" Value="False">
                                    <Setter TargetName="details" Property="Visibility" Value="Collapsed" />
                                </DataTrigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </DataGrid.ItemContainerStyle>
    </DataGrid>
</Window>

示例

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new List<RowViewModelBase> {
            new EmptySpaceViewModel(),
            new DataViewModel("aaaa", "bbb"),
            new EmptySpaceViewModel(),
            new DataViewModel("aaaa", "bbb"),
            new CommentViewModel("//comment"),
            new DataViewModel("aaaa", "bbb"),
            new CommentViewModel("//comment"),
            new CommentViewModel("//comment"),
            new DataViewModel("aaaa", "bbb"),
        };
    }
}

当然,如果您有一种替代模板 - 您不需要模板选择器,可以直接设置模板

<DataGrid.RowDetailsTemplate>
    <DataTemplate>
            <TextBlock Text="{Binding Comment}" />
    </DataTemplate>
</DataGrid.RowDetailsTemplate>

enter image description here

viewmodel for data and comment. Also for empty space.

public abstract class RowViewModelBase
{
    public bool IsSpecial { get; set; }
}

public class EmptySpaceViewModel : RowViewModelBase
{
    public EmptySpaceViewModel() => IsSpecial = true;
}

public class DataViewModel : RowViewModelBase
{
    public DataViewModel(string column1, string column2)
    {
        Column1 = column1;
        Column2 = column2;
    }

    public string Column1 { get; set; }
    public string Column2 { get; set; }
}

public class CommentViewModel : RowViewModelBase
{
    public string Comment { get; }

    public CommentViewModel(string comment)
    {
        Comment = comment;
        IsSpecial = true;
    }
}

template selector

public class RowContentSelector : DataTemplateSelector
{
    public DataTemplate EmptyTemplate { get; set; }
    public DataTemplate CommentTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item is EmptySpaceViewModel)
            return EmptyTemplate;
        if (item is CommentViewModel)
            return CommentTemplate;
        return base.SelectTemplate(item, container);
    }
}

xaml

<Window
    ...>
    <Window.Resources>
        <DataTemplate x:Key="EmptyRow">
            <Border Height="30" />
        </DataTemplate>
        <DataTemplate x:Key="CommentTempate">
            <TextBlock Foreground="Green" Text="{Binding Comment}" />
        </DataTemplate>
        <local:RowContentSelector
            x:Key="RowContentSelector"
            CommentTemplate="{StaticResource CommentTempate}"
            EmptyTemplate="{StaticResource EmptyRow}" />
    </Window.Resources>

    <DataGrid
        AutoGenerateColumns="False"
        CanUserAddRows="False"
        ItemsSource="{Binding}"
        RowDetailsTemplateSelector="{StaticResource RowContentSelector}"
        RowDetailsVisibilityMode="Visible">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Column1}" Header="column1" />
            <DataGridTextColumn Binding="{Binding Column2}" Header="column2" />
        </DataGrid.Columns>
        <DataGrid.ItemContainerStyle>
            <Style TargetType="{x:Type DataGridRow}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type DataGridRow}">
                            <Border
                                x:Name="DGR_Border"
                                Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                SnapsToDevicePixels="True">
                                <SelectiveScrollingGrid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto" />
                                        <ColumnDefinition Width="*" />
                                    </Grid.ColumnDefinitions>

                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="*" />
                                        <RowDefinition Height="Auto" />
                                    </Grid.RowDefinitions>

                                    <DataGridCellsPresenter
                                        x:Name="cells"
                                        Grid.Column="1"
                                        ItemsPanel="{TemplateBinding ItemsPanel}"
                                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />

                                    <DataGridDetailsPresenter
                                        x:Name="details"
                                        Grid.Row="1"
                                        Grid.Column="1"
                                        SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=AreRowDetailsFrozen, Converter={x:Static DataGrid.RowDetailsScrollingConverter}, ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical}}"
                                        Visibility="{TemplateBinding DetailsVisibility}" />

                                    <DataGridRowHeader
                                        x:Name="header"
                                        Grid.RowSpan="2"
                                        SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical"
                                        Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=HeadersVisibility, Converter={x:Static DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static DataGridHeadersVisibility.Row}}" />
                                </SelectiveScrollingGrid>
                            </Border>
                            <ControlTemplate.Triggers>
                                <DataTrigger Binding="{Binding IsSpecial}" Value="True">
                                    <Setter TargetName="cells" Property="Visibility" Value="Collapsed" />
                                    <!--<Setter TargetName="header" Property="Visibility" Value="Collapsed" />-->
                                </DataTrigger>
                                <DataTrigger Binding="{Binding IsSpecial}" Value="False">
                                    <Setter TargetName="details" Property="Visibility" Value="Collapsed" />
                                </DataTrigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </DataGrid.ItemContainerStyle>
    </DataGrid>
</Window>

example

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new List<RowViewModelBase> {
            new EmptySpaceViewModel(),
            new DataViewModel("aaaa", "bbb"),
            new EmptySpaceViewModel(),
            new DataViewModel("aaaa", "bbb"),
            new CommentViewModel("//comment"),
            new DataViewModel("aaaa", "bbb"),
            new CommentViewModel("//comment"),
            new CommentViewModel("//comment"),
            new DataViewModel("aaaa", "bbb"),
        };
    }
}

Of course, if you has one alternative template - you no need template selector and can set template directly

<DataGrid.RowDetailsTemplate>
    <DataTemplate>
            <TextBlock Text="{Binding Comment}" />
    </DataTemplate>
</DataGrid.RowDetailsTemplate>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文