仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 878|回复: 8
打印 上一主题 下一主题

[学习教程] ASP.NET教程之在ListView的GroupItem头中显现每列的Summary仓酷云

[复制链接]
精灵巫婆 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-18 11:18:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
来吧!老师们!我代表千千万万的asp.net/C#的初学者在这里呼唤着!成绩形貌

WPF自带的ListView和DataGrid控,都供应了数据分组的撑持,并能够对分组的Header举行自界说。可是,假如想在每一个分组的Header中,显现出天职组的"小计"就不是一件简单的事变了。
假定要用一个ListView用于显现全校先生成就。按班级分组,并在分组头中显现班级均匀分。
最后的效果大抵以下:

.在分组的Header中显现天职组的Aggregation
怎样?有甚么思绪?完成的难点有:

  • GroupHeader中的第一例显现为分组的称号。
  • GroupHeader中的别的列与数据分歧。
  • GroupHeader中各列的宽度与ListView中列对应一直分歧。
  • GroupHeader中各列的对齐体例与ListView中各列分歧。
数据

Model层只要一个类,ScoreInfo,代码以下:

publicclassScoreInfo
{
publicScoreInfo(stringstudentNo,stringclassName,intmath,intenglish)
{
StudentNo=studentNo;
ClassName=className;
MathScore=math;
EnglishScore=english;
}

publicstringStudentNo{get;set;}

publicstringClassName{get;set;}

publicintMathScore{get;set;}

publicintEnglishScore{get;set;}

[ReadOnly(true)]
publicintTotalScore
{
get{returnMathScore+EnglishScore;}
}
}

一次测验中,先生的这些数据都不会变。以是不必要完成INotifyPropertyChanged接口。
DAL层间接前往假数据,代码以下:

publicclassSchoolScoreProvider
{
publicList<ScoreInfo>ReadAllScoreInfo()
{
varrandom=newRandom();
return(fromiinEnumerable.Range(0,4)
letclassName=String.Format("({0})班",i+1)

fromsinEnumerable.Range(i*6+1,6)
letmScore=random.Next(101)
leteScore=random.Next(101)

selectnewScoreInfo(s.ToString(),className,mScore,eScore))
.ToList();
}
}

在XAML中声明(实体化)数据源,代码以下:

<!--PrepareDataSource-->
<!--Justfordemo,DONTinitializeyourDataSourcethiswayinrealproject.-->
<ObjectDataProviderx:Key="Data"
ObjectType="{x:Typel:SchoolScoreProvider}"
MethodName="ReadAllScoreInfo"/>
<CollectionViewSourcex:Key="DataView"
Source="{StaticResourceData}">
<!--GroupByClassName-->
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescriptionPropertyName="ClassName"/>
</CollectionViewSource.GroupDescriptions>
<!--SortByTotalScore-->
<CollectionViewSource.SortDescriptions>
<c:SortDescriptionPropertyName="TotalScore"Direction="Descending"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>

UI层代码

然后是ListView的界说:

<ListViewDataContext="{StaticResourceDataView}"
ItemsSource="{Binding}">
<!--SpecifythecurrentListViewshouldGroupdatasourceitems.-->
<ListView.GroupStyle>
<GroupStyle/>
</ListView.GroupStyle>
<ListView.View>
<GridView>
<!--CellTemplateistheonlyNORMALwaytomakethecolumntextrightalign.-->
<!--ThefollowingcodeshouldworkswiththedefaultListViewItemstyleaboveinResources.
BUTitdoesnt.
<GridViewColumnHeader="学号"Width="75"
DisplayMemberBinding="{BindingStudentNo}"
TextBlock.TextAlignment="Right"/>
Think,ifyouneedtochangetheAlignmentwhilerunning.Theirdifferenceswillbeobvious.
-->
<GridViewColumnHeader="学号"Width="75">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlockText="{BindingStudentNo}"
TextAlignment="Right"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumnHeader="数学成就"Width="75">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlockText="{BindingMathScore}"
TextAlignment="Right"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumnHeader="英语成就"Width="75">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlockText="{BindingEnglishScore}"
TextAlignment="Right"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>

为了让Group撑持排列,间接能想到的办法就是在个中安排一个ListViewItem。经由实验这个计划是可行的。必要自界说GroupItem的ControlTemplate。代码以下:

<!--CustomGroupItemtosupportgroupcollaps/expand-->
<StyleTargetType="{x:TypeGroupItem}">
<SetterProperty="Template">
<Setter.Value>
<ControlTemplateTargetType="{x:TypeGroupItem}">
<Grid>
<Grid.RowDefinitions>
<RowDefinitionHeight="Auto"/>
<RowDefinitionHeight="*"/>
</Grid.RowDefinitions>
<ListViewItemStyle="{StaticResourceGroupHeaderListViewItemStyle}"
Content="{BindingConverter={StaticResourceGroupDataAggregator}}"/>
<ToggleButtonName="expander"
Style="{StaticResourceToggleExpanderStyle}"/>
<ItemsPresenterGrid.Row="1"
Visibility="{BindingIsChecked,ElementName=expander,Converter={StaticResourceBooleanToVisibilityConverter}}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

个中的关头点是,在内里放了一个ListViewItem。这里间接放GridViewRowPresenter也是能够准确显现出数据的,可是因为没有ListViewItem作Host,每列中的笔墨会一直向左对齐。
利用一个Converter,对以后组的数据举行Aggregation,天生一个暗示班级均匀分的ScoreInfo。Convert的代码以下:

publicclassGroupDataAggregator:IValueConverter
{
publicobjectConvert(objectvalue,Typetype,objectarg,CultureInfoculture)
{
vargroupData=valueasCollectionViewGroup;
if(groupData!=null)
{
varscores=groupData.Items.Cast<ScoreInfo>();
varavgMath=(int)scores.Average(x=>x.MathScore);
varavgEng=(int)scores.Average(x=>x.EnglishScore);

returnnewScoreInfo(groupData.Name.ToString(),null,avgMath,avgEng);
}

returnnewInvalidOperationException();
}

publicobjectConvertBack(objectvalue,Typetype,objectarg,CultureInfoculture)
{
thrownewNotImplementedException();
}
}

固然,这个Convert其实不重点。另外一个重点是,要为GroupItem中的ListViewItem写一个特别的Style,不然,甚么工具都看不到。

<!--StyleapplytoallListViewItem,tomakeitscellstretch.-->
<StyleTargetType="{x:TypeListViewItem}">
<SetterProperty="HorizontalContentAlignment"Value="Stretch"/>
</Style>

<!--StyleapplytotheListViewIteminGroupItemheader-->
<Stylex:Key="GroupHeaderListViewItemStyle"
TargetType="{x:TypeListViewItem}"
BasedOn="{StaticResource{x:TypeListViewItem}}">
<SetterProperty="Template">
<Setter.Value>
<ControlTemplateTargetType="{x:TypeListViewItem}">
<!--KEYSTEP:BindingtheColumnstoListViews-->
<GridViewRowPresenterColumns="{BindingView.Columns,RelativeSource={RelativeSourceMode=FindAncestor,AncestorType={x:TypeListView}}}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

关头的一步就是给GridViewRowPresenter指定Columns,ListView可不会主动为这个外人设置这个属性的。
再归去讲GroupItem,用于睁开GroupItem的是其Template中的ToggleButton,即图中三角图标。其代码以下:

<!--ThetogglebuttoninGroupItemHeader,usedtoexpand/collapsagroup-->
<Stylex:Key="ToggleExpanderStyle"
TargetType="{x:TypeToggleButton}">
<SetterProperty="Width"Value="16"/>
<SetterProperty="Height"Value="16"/>
<SetterProperty="HorizontalAlignment"Value="Left"/>
<SetterProperty="VerticalAlignment"Value="Center"/>
<SetterProperty="HorizontalContentAlignment"Value="Center"/>
<SetterProperty="VerticalContentAlignment"Value="Center"/>
<SetterProperty="IsChecked"Value="True"/>
<SetterProperty="BorderThickness"Value="1"/>
<SetterProperty="BorderBrush"Value="Black"/>
<SetterProperty="Background"Value="Black"/>
<SetterProperty="Padding"Value="0"/>
<SetterProperty="SnapsToDevicePixels"Value="True"/>
<SetterProperty="FocusVisualStyle"Value="{x:Null}"/>
<SetterProperty="IsTabStop"Value="False"/>
<SetterProperty="Content">
<Setter.Value>
<StreamGeometry>M6,0L6,6L0,6Z</StreamGeometry>
</Setter.Value>
</Setter>
<SetterProperty="Template">
<Setter.Value>
<ControlTemplateTargetType="{x:TypeToggleButton}">
<!--Theborderisusedtomakethecontrolarectanglewhichiseasiertoclick.-->
<BorderBackground="Transparent"
BorderThickness="0">
<PathStretch="None"
Data="{TemplateBindingContent}"
Margin="{TemplateBindingPadding}"
Fill="{TemplateBindingBackground}"
Stroke="{TemplateBindingBorderBrush}"
StrokeThickness="{TemplateBindingBorderThickness}"
VerticalAlignment="{TemplateBindingVerticalContentAlignment}"
HorizontalAlignment="{TemplateBindingHorizontalContentAlignment}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<TriggerProperty="IsMouseOver"Value="True">
<SetterProperty="Background"Value="#007ACC"/>
<SetterProperty="BorderBrush"Value="#007ACC"/>
</Trigger>
<TriggerProperty="IsChecked"Value="False">
<SetterProperty="Background"Value="White"/>
<SetterProperty="Content">
<Setter.Value>
<StreamGeometry>M0,0L4,4L0,8Z</StreamGeometry>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>

题外话

另给勤劳些、不喜好吃冷饭的同砚几个思索的偏向,用于确认对下面代码的了解水平。
针对下面这个ToggleButton的Style:

  • 每一个Setter都有甚么感化?删除每个都有甚么分歧成果?哪些是能够删除的?(用时5分钟)
  • 利用TemplateBinding与间接在ControlTemplate中写值有甚么分歧?(30秒)
  • 为何把BorderThickness绑定给了Path,而不是Border?(30秒)
  • Style中的Trigger可否放在ControlTemplate.Triggers中?为何利用StyleTrigger而不是ControlTemplateTrigger?(5分钟)
  • 假如你不会StreamGeometry中的语法,那末实验解读StreamGeometry中的语法(个中Z暗示曲线向原点闭合),并写出一个+-号作风的ToggleButtonStyle。(15分钟)
假如只是要计划。这里是完全的代码。
那做企业软件是不是最好用J2EE?
变相怪杰 该用户已被删除
沙发
发表于 2015-1-20 19:59:39 | 只看该作者
是目前ASP在UNIX/Linux上的应用可以说几乎为0)。所以平台的局限性和ASP自身的安全性限制了ASP的广泛应用。
兰色精灵 该用户已被删除
板凳
发表于 2015-1-20 22:10:03 | 只看该作者
现在主流的网站开发语言无外乎asp、php、asp.net、jsp等。
愤怒的大鸟 该用户已被删除
地板
发表于 2015-1-26 14:10:50 | 只看该作者
通过这次激烈的讨论,我从大家身上学到了太多,开阔了眼界,不管是支持我的还是骂我的,都感谢你们。
冷月葬花魂 该用户已被删除
5#
发表于 2015-2-4 14:55:53 | 只看该作者
比如封装性、继承性、多态性等等,这就解决了刚才谈到的ASP的那些弱点。封装性使得代码逻辑清晰,易于管理,并且应用到ASP.Net上就可以使业务逻辑和Html页面分离,这样无论页面原型如何改变。
6#
发表于 2015-2-28 14:33:54 | 只看该作者
ASP.NET:ASP.net是Microsoft.net的一部分,作为战略产品,不仅仅是ActiveServerPage(ASP)的下一个版本;它还提供了一个统一的Web开发模型,其中包括开发人员生成企业级Web应用程序所需的各种服务。ASP.NET的语法在很大程度上与ASP兼容,同时它还提供一种新的编程模型和结构,可生成伸缩性和稳定性更好的应用程序,并提供更好的安全保护。
飘飘悠悠 该用户已被删除
7#
发表于 2015-3-9 23:51:58 | 只看该作者
可以看作是VC和Java的混合体吧,尽管MS自己讲C#内核中更多的象VC,但实际上我还是认为它和Java更象一些吧。首先它是面向对象的编程语言,而不是一种脚本,所以它具有面向对象编程语言的一切特性。
不帅 该用户已被删除
8#
发表于 2015-3-12 15:19:13 | 只看该作者
在asp.net虚拟主机的服务提供商中,目前首推的是CNNIC的其中一家域名注册机构---时代互联(www.now.net.cn),他们早在2001年微软刚推出Asp.net时就推出了对应的Asp.net虚拟主机了,经笔者的使用测试,他提供的Asp.net性能非常的稳定,版本也会定期的更新,目前他的
金色的骷髅 该用户已被删除
9#
发表于 2015-3-19 23:23:07 | 只看该作者
ASP是把代码交给VBScript解释器或Jscript解释器来解释,当然速度没有编译过的程序快了。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-12-23 17:55

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表