我一直在使用David Poll's CollectionPrinter Control并已成功打印使用DataGrid显示集合的报表。如果不在数据网格中使用分组,它会正常地对文档进行分页。但是,只要我按照上述链接中的第一条评论中的说明激活分组,网格就会尝试显示第一页中的所有项目并被切断(不再分页)。
以下是我尝试用于分组DataGrid的代码:
<Printing:CollectionPrinter.BodyTemplate>
<DataTemplate>
<Grid Height="Auto">
<Grid.Resources>
<CollectionViewSource x:Key="groupedCollection" Source="{Binding CurrentItems}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="BaFolioNum" />
<PropertyGroupDescription PropertyName="CategoryDesc"/>
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</Grid.Resources>
<sdk:DataGrid ItemsSource="{Binding Source={StaticResource groupedCollection}}" AutoGenerateColumns="False"
VerticalScrollBarVisibility="Disabled">
<sdk:DataGrid.Resources>
</sdk:DataGrid.Resources>
<sdk:DataGrid.RowGroupHeaderStyles>
<Style TargetType="sdk:DataGridRowGroupHeader">
<Setter Property="PropertyNameVisibility" Value="Collapsed"/>
<Setter Property="SublevelIndent" Value="10" />
</Style>
</sdk:DataGrid.RowGroupHeaderStyles>
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Binding="{Binding SkU}" Header="SKU" MinWidth="150" />
<sdk:DataGridTextColumn Binding="{Binding ItemDesc}" Header="Product Description" Width="*"/>
<sdk:DataGridTextColumn Binding="{Binding CorrectionsDisplay}" Header="Corrections?" />
<sdk:DataGridTextColumn Binding="{Binding QtyLocDisplay}" Header="Qty/Loc"/>
</sdk:DataGrid.Columns>
</sdk:DataGrid>
</Grid>
</DataTemplate>
</Printing:CollectionPrinter.BodyTemplate>
如果有人有运气分组数据并使用他的方法打印,我会非常感谢你,如果你可以帮助我。
答案 0 :(得分:0)
请参阅我在http://www.davidpoll.com/2010/04/16/making-printing-easier-in-silverlight-4#comment-7197网站上发布的评论,了解我为实现目标所做的工作。 我会在有时间的时候提出我改变的代码。
编辑:正如所承诺的,以下是我为分组工作所做的更改。
首先,我向Printing.Controls项目添加了两个接口
public interface IContainsCollectionViewSource
{
CollectionViewSource PageCollectionSource { get; set; }
}
和
public interface IContainsContext
{
IContainsCollectionViewSource CollectionContext { get; }
}
在CollectionPrintContext.cs中,我添加了以下属性来容纳CollectionViewSource
private CollectionViewSource displayCollectionViewSource;
/// <summary>
/// Gets or sets the data grid collection view which can be used to group and sort the display control.
/// </summary>
public CollectionViewSource DisplayCollectionViewSource
{
get
{
return this.displayCollectionViewSource;
}
set
{
if (!object.Equals(this.displayCollectionViewSource, value))
{
this.displayCollectionViewSource = value;
PropertyChanged.Raise(this, new PropertyChangedEventArgs("DisplayCollectionViewSource"));
}
}
}
在CollectionPrinter.cs中,我修改了CalculateChild。新代码有标记的评论
private void CalculateChild<T>(object signal)
{
Debug.Assert(!this._IsRoot);
Popup popup = new Popup();
Grid layoutContainer;
popup.Child = layoutContainer = new Grid();
layoutContainer.Children.Add(this);
popup.Opacity = 0;
layoutContainer.Opacity = 0;
layoutContainer.IsHitTestVisible = false;
popup.IsHitTestVisible = false;
this.Width = popup.Width = this.CurrentPrintContext.PrintableArea.Width;
this.Height = popup.Height = this.CurrentPrintContext.PrintableArea.Height;
var items = (this.ItemsSource ?? new T[0]).Cast<T>().Skip(this.CurrentPrintContext.FirstItemIndex).ToArray();
ObservableCollection<T> pageItems = new ObservableCollection<T>();
this.CurrentPrintContext.CurrentItems = pageItems;
//New Code Block Starts Here
if (this.CurrentPrintContext.Host as IContainsContext != null)
{
if (((IContainsContext)this.CurrentPrintContext.Host).CollectionContext != null)
{
this.CurrentPrintContext.DisplayCollectionViewSource = new CollectionViewSource();
foreach (GroupDescription groupDescription in ((IContainsContext)this.CurrentPrintContext.Host).CollectionContext.PageCollectionSource.GroupDescriptions)
{
this.CurrentPrintContext.DisplayCollectionViewSource.GroupDescriptions.Add(groupDescription);
}
foreach (SortDescription sortDescription in ((IContainsContext)this.CurrentPrintContext.Host).CollectionContext.PageCollectionSource.SortDescriptions)
{
this.CurrentPrintContext.DisplayCollectionViewSource.SortDescriptions.Add(sortDescription);
}
this.CurrentPrintContext.DisplayCollectionViewSource.Source = pageItems;
}
}
//New Code Block Ends Here
this.Dispatcher.DelayUntil(() =>
{
try
{
this.CurrentPrintContext.IsLastPage = false;
bool reachedEnd = false;
int itemsAdded = 0;
do
{
if (itemsAdded >= items.Length ||
(this.MaximumItemsPerPage != -1 && itemsAdded >= this.MaximumItemsPerPage))
{
reachedEnd = true;
break;
}
pageItems.Add(items[itemsAdded++]);
this.CurrentPrintContext.LastItemIndex = this.CurrentPrintContext.FirstItemIndex +
itemsAdded - 1;
if (itemsAdded == items.Length)
this.CurrentPrintContext.IsLastPage = true;
this.CurrentPrintContext.NotifyPropertiesChanged();
//New Code Block Starts Here
if (this.CurrentPrintContext.DisplayCollectionViewSource != null) this.CurrentPrintContext.DisplayCollectionViewSource.View.Refresh();
//New Code Block Ends Here
//popup.UpdateLayout();
this._VisualChild.Measure(this.CurrentPrintContext.PrintableArea);
} while (this.CheckWidth() && this.CheckHeight());
while (!reachedEnd && itemsAdded != 1 &&
!(this.CheckExpandedWidth() && this.CheckExpandedHeight() &&
this.CheckExpandedWidthHeight()))
{
pageItems.RemoveAt(pageItems.Count - 1);
itemsAdded--;
this.CurrentPrintContext.LastItemIndex = this.CurrentPrintContext.FirstItemIndex +
itemsAdded - 1;
this.CurrentPrintContext.IsLastPage = false;
this.CurrentPrintContext.NotifyPropertiesChanged();
}
this.Dispatcher.BeginInvoke(() =>
{
DriveAnimationsToCompletion(popup);
this.Dispatcher.BeginInvoke(() =>
{
popup.IsOpen = false;
popup.Child = null;
layoutContainer.Children.Clear();
lock (signal)
Monitor.Pulse(signal);
});
});
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
},
() => this._VisualChild != null);
popup.IsOpen = true;
}
在我的打印机的cs文件中,我设置了排序和分组。有一点需要注意的是我设置它的方式,这个PageCollectionViewSource仅用作分组和排序的模板。没有数据存储在其中。
public partial class InventoryPrinter : CollectionPrinter, IContainsContext
{
private InvReportData context;
public InvReportData Context
{
get
{
return context;
}
set
{
context = value;
try
{
context.PageCollectionSource = new CollectionViewSource() ;
//context.PageCollectionSource.SortDescriptions.Add(new SortDescription("SkuP1nBr", ListSortDirection.Ascending));
//context.PageCollectionSource.SortDescriptions.Add(new SortDescription("SkuP2tXt", ListSortDirection.Ascending));
//context.PageCollectionSource.SortDescriptions.Add(new SortDescription("SkuP3nBr", ListSortDirection.Ascending));
//context.PageCollectionSource.SortDescriptions.Add(new SortDescription("SkuP4tXt", ListSortDirection.Ascending));
//context.PageCollectionSource.SortDescriptions.Add(new SortDescription("SkuP5", ListSortDirection.Ascending));
//context.PageCollectionSource.SortDescriptions.Add(new SortDescription("BaFolioNum", ListSortDirection.Ascending));
//context.PageCollectionSource.GroupDescriptions.Add(new PropertyGroupDescription("BaFolioNum"));
context.PageCollectionSource.GroupDescriptions.Add(new PropertyGroupDescription("BaFolioDisplay"));
context.PageCollectionSource.GroupDescriptions.Add(new PropertyGroupDescription("CategoryDesc"));
}
catch (Exception)
{
throw;
}
}
}
public IContainsCollectionViewSource CollectionContext
{
get
{
return context;
}
}
public InventoryPrinter()
{
InitializeComponent();
}
}
我使用的InvReportData类来填充页眉和页脚中的信息,它看起来像这样
public class InvReportData : IContainsCollectionViewSource
{
public string BoatName { get; set; }
public string ReportTypeLabel { get; set; }
public string Date { get; set; }
public CollectionViewSource PageCollectionSource { get; set; }
}
我的模板的xaml代码绑定到DisplayCollectionViewSource.View而不是CurrentItems属性
<Printing:CollectionPrinter.FooterTemplate>
<DataTemplate>
<Grid>
<TextBlock HorizontalAlignment="Left" Text="{Binding Host.Context.Date}" />
<StackPanel HorizontalAlignment="Right"
Orientation="Horizontal">
<TextBlock Text="{Binding CurrentPage, StringFormat='{}Page {0} '}" />
<TextBlock Text="{Binding PageCount, StringFormat='{}/ {0}'}" />
</StackPanel>
</Grid>
</DataTemplate>
</Printing:CollectionPrinter.FooterTemplate>
<Printing:CollectionPrinter.BodyTemplate>
<DataTemplate>
<sdk:DataGrid x:Name="ReportDataGrid" ItemsSource="{Binding DisplayCollectionViewSource.View}" AutoGenerateColumns="False"
VerticalScrollBarVisibility="Disabled">
<sdk:DataGrid.RowGroupHeaderStyles>
<Style TargetType="sdk:DataGridRowGroupHeader">
<Setter Property="PropertyNameVisibility" Value="Collapsed"/>
<Setter Property="ItemCountVisibility" Value="Collapsed" />
<Setter Property="SublevelIndent" Value="10" />
</Style>
</sdk:DataGrid.RowGroupHeaderStyles>
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Binding="{Binding SkU}" Header="SKU" MinWidth="150" />
<sdk:DataGridTextColumn Binding="{Binding ItemDesc}" Header="Product Description" Width="*"/>
<sdk:DataGridTextColumn Binding="{Binding CorrectionsDisplay}" Header="Corrections?" />
<sdk:DataGridTextColumn Binding="{Binding QtyLocDisplay}" Header="Qty/Loc"/>
</sdk:DataGrid.Columns>
</sdk:DataGrid>
</DataTemplate>
</Printing:CollectionPrinter.BodyTemplate>
最后一段代码需要放在窗口/控件中,显示/打印打印机。在这里,您使用数据设置CollectionViewSource并将其设置为打印机的ItemsSource
InvReportData headerFooterData = new InvReportData();
headerFooterData.BoatName = boatName;
headerFooterData.Date = DateTime.Today.ToString("dddd, dd MMMM yyyy");
CollectionSource = new CollectionViewSource { Source = reportData }.View;
CollectionSource.SortDescriptions.Add(new SortDescription("BaFolioNum", ListSortDirection.Ascending));
CollectionSource.SortDescriptions.Add(new SortDescription("SkuP1nBr", ListSortDirection.Ascending));
CollectionSource.SortDescriptions.Add(new SortDescription("SkuP2tXt", ListSortDirection.Ascending));
CollectionSource.SortDescriptions.Add(new SortDescription("SkuP3nBr", ListSortDirection.Ascending));
CollectionSource.SortDescriptions.Add(new SortDescription("SkuP4tXt", ListSortDirection.Ascending));
CollectionSource.SortDescriptions.Add(new SortDescription("SkuP5", ListSortDirection.Ascending));
//CollectionSource.GroupDescriptions.Add(new PropertyGroupDescription("BaFolioNum"));
CollectionSource.GroupDescriptions.Add(new PropertyGroupDescription("BaFolioDisplay"));
CollectionSource.GroupDescriptions.Add(new PropertyGroupDescription("CategoryDesc"));
printer.ItemsSource = CollectionSource;
printer.Context = headerFooterData;
这些应该是您必须进行的所有更改才能使分组与datagrids一起使用。享受。