c# – 在多行条件下格式化WPF DataGrid

c# – 在多行条件下格式化WPF DataGrid,第1张

概述我有一个 WPF DataGrid与这样的数据 Number | Attribute | Old | New |=============================================|1 | Height | 1.1 | 0.9 |--------+------------+---------+--- 我有一个 WPF DataGrID与这样的数据

Number  | Attribute  | old     | New         |=============================================|1       | Height     | 1.1     | 0.9         |--------+------------+---------+-------------|1       | Material   | Steel1  | Steel2      |--------+------------+---------+-------------|2       | color      | Green   | light-Green |--------+------------+---------+-------------|

由于相同的数字,前两个记录属于一起,我想删除两个记录之间的边界,所以它看起来像这样

Number  | Attribute  | old     | New         |=============================================|1       | Height     | 1.1     | 0.9         |1       | Material   | Steel1  | Steel2      |--------+------------+---------+-------------|2       | color      | Green   | light-Green |--------+------------+---------+-------------|

我有一种方法来加载格式化

private voID myGrID_LoadingRow(object sender,DataGrIDRowEventArgs e) {        ...}

但是这只能在这一行的数据上格式化,而且我不知道之后或之前的哪一行.所以我无法决定如何格式化此行的边框.

如何根据不仅当前行但上一行和后一行的信息来格式化行?

解决方法 我写了一个简单的示例应用程序,它只有一个XAML文件和代码隐藏.要重新创建我所做的,只需创建一个新的WPF 4.5应用程序,并将下面的代码粘贴到正确的文件中.

我的解决方案使用视图模型,它允许您使用数据绑定执行所有 *** 作(并且不需要您在代码隐藏中连接事件).

这可能看起来比您预期的代码要多得多,但请记住,这是一个完整的示例,其中很多只是设置.对于真正重要的代码,希望你会发现,即使它增加了相当多的行,它为你提供了一个非常强大的模板,用于在WPF中创建各种很酷的用户界面.我在每个代码文件后添加了一些注释,希望能让它更容易理解代码的作用.

MainWindow.xaml

<Window x:Class="WpfApplication1.MainWindow"        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"        title="MainWindow"        Height="350"        WIDth="525"        d:DataContext="{d:DesignInstance Type=wpfApplication1:Mainviewmodel,IsDesignTimeCreatable=False}">    <DataGrID autoGenerateColumns="False"              ItemsSource="{Binding AttributeUpdateviewmodels}"              GrIDlinesVisibility="Vertical">        <DataGrID.RowStyle>            <Style targettype="DataGrIDRow">                <Setter Property="borderThickness"                        Value="{Binding borderThickness}" />                <Setter Property="borderBrush"                        Value="Black" />            </Style>        </DataGrID.RowStyle>        <DataGrID.Columns>            <DataGrIDTextColumn header="Number"                                Binding="{Binding Number}" />            <DataGrIDTextColumn header="Attribute"                                Binding="{Binding Attribute}" />            <DataGrIDTextColumn header="old"                                Binding="{Binding old}" />            <DataGrIDTextColumn header="New"                                Binding="{Binding New}" />        </DataGrID.Columns>    </DataGrID></Window>

这基本上只是一个带有文本列的简单数据网格.神奇的是自定义行样式,可根据需要创建水平网格线. (有关数据绑定的更多详细信息,请参见下文.)

MainWindow.xaml.cs(即代码隐藏):

using System.Collections.Generic;using System.linq;using System.windows;namespace WpfApplication1{    public partial class MainWindow : Window    {        public MainWindow()        {            InitializeComponent();            DataContext = new Mainviewmodel();        }    }    public class Mainviewmodel    {        public List<AttributeUpdateviewmodel> AttributeUpdateviewmodels { get; set; }        public Mainviewmodel()        {            var rawAttributeUpdates = new[]            {            new AttributeUpdate { Number = 1,Attribute = "Height",old = "1.1",New = "0.9" },new AttributeUpdate { Number = 1,Attribute = "Material",old = "Steel1",New = "Steel2" },new AttributeUpdate { Number = 2,Attribute = "color",old = "Green",New = "light-Green" },new AttributeUpdate { Number = 3,Attribute = "Attribute4",old = "old4",New = "New4" },Attribute = "Attribute5",old = "old5",New = "New5" },Attribute = "Attribute6",old = "old6",New = "New6" },new AttributeUpdate { Number = 4,Attribute = "Attribute7",old = "old7",New = "New7" },new AttributeUpdate { Number = 5,Attribute = "Attribute8",old = "old8",New = "New8" },Attribute = "Attribute9",old = "old9",New = "New9" },Attribute = "Attribute10",old = "old10",New = "New10" }            };            var sortedAttributeUpdates = rawAttributeUpdates.OrderBy(x => x.Number);            var groupedAttributeUpdates = sortedAttributeUpdates                .GroupBy(x => x.Number);            AttributeUpdateviewmodels = sortedAttributeUpdates                .Select(x => GetAttributeUpdateRow(x,groupedAttributeUpdates))                .ToList();        }        private AttributeUpdateviewmodel GetAttributeUpdateRow(            AttributeUpdate attributeUpdate,IEnumerable<IGrouPing<int,AttributeUpdate>> groupedAttributeUpdates)        {            var lastInGroup = groupedAttributeUpdates.Single(x => x.Key == attributeUpdate.Number).Last();            return new AttributeUpdateviewmodel            {                Number = attributeUpdate.Number,Attribute = attributeUpdate.Attribute,New = attributeUpdate.New,old = attributeUpdate.old,IsLastInGroup = attributeUpdate == lastInGroup            };        }    }    public class AttributeUpdate    {        public int Number { get; set; }        public string Attribute { get; set; }        public string old { get; set; }        public string New { get; set; }    }    public class AttributeUpdateviewmodel    {        public int Number { get; set; }        public string Attribute { get; set; }        public string old { get; set; }        public string New { get; set; }        public bool IsLastInGroup { get; set; }        public Thickness borderThickness        {            get { return IsLastInGroup ? new Thickness(0,1) : new Thickness(); }        }    }}

基本上,我假设您在表的每一行中显示的数据是AttributeUpdate. (我刚刚做了,你可能有一个更好的名字.)

由于AttributeUpdate是纯数据并且与数据的格式化无关,因此我创建了一个AttributeUpdateviewmodel来组合显示所需的数据和格式信息.

因此,AttributeUpdate和AttributeUpdateviewmodel共享相同的数据,但视图模型添加了一些处理格式的属性.

用于格式化的新属性是什么?

> IsLastInGroup – 相关行是否是其组的最后一行(组中的所有项共享相同的数字).
> borderThickness – 边框的厚度.在这种情况下,如果项目在组中的最后一个,则底部边框为1,其他所有项为零,否则为0.

数据绑定在XAML文件中显示为{Binding name_of_property},只需点击视图模型中的数据和格式信息即可.如果基础数据在应用程序运行期间可能发生变化,您将需要让视图模型实现INotifyPropertyChanged interface. INotifyPropertyChanged实际上为您的应用程序添加了“更改检测”,允许您的绑定自动重新绑定到新的/更改的数据.

最后一点是我使用LINQ query来处理分组逻辑.此特定查询按Number对行进行排序,然后按Number对它们进行分组.然后,它创建AttributeUpdateviewmodel实例,根据当前AttributeUpdate是否与其组中的最后一项匹配来填充IsLastInGroup.

注意:为了简单起见,我将几个类放在一个文件中.通常的约定是每个文件一个类,因此您可能希望将每个类分解为自己的文件.

结果

编辑

@Mike Strobel的评论指出按数字排序可能不一定是可取的.例如,用户可能希望按其他列排序,但仍会看到按Number分组的行.我不确定这是一个常见的用例,但是如果这是一个要求,你可以简单地用另一个将“当前”值与“next”值进行比较的liNQ查询替换,然后确定Number是否改变.这是我的解决方案:

var nextAttributeUpdates = rawAttributeUpdates    .Skip(1)    .Concat(new[] { new AttributeUpdate { Number = -1 } });AttributeUpdateviewmodels = rawAttributeUpdates    .Zip(        nextAttributeUpdates,(c,n) => new { Current = c,NextNumber = n.Number })    .Select(        x => new AttributeUpdateviewmodel        {            Number = x.Current.Number,Attribute = x.Current.Attribute,New = x.Current.New,old = x.Current.old,IsLastInGroup = x.Current.Number != x.NextNumber        })    .ToList();
总结

以上是内存溢出为你收集整理的c# – 在多行条件下格式化WPF DataGrid全部内容,希望文章能够帮你解决c# – 在多行条件下格式化WPF DataGrid所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1219280.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存