Voir le commentaire J'ai posté sur son site Web au http://www.davidpoll.com/2010/04/16/making-printing-easier-in-silverlight-4#comment-7197 pour une explication de ce que j'ai fait pour le faire fonctionner. Je vais mettre en place le code que j'ai changé dès que j'ai un peu de temps. Edit: Comme promis, voici les changements que j'ai faits pour que le travail de groupe fonctionne bien.
D'abord, j'ajouté deux interfaces au projet Printing.Controls
public interface IContainsCollectionViewSource
{
CollectionViewSource PageCollectionSource { get; set; }
}
et
public interface IContainsContext
{
IContainsCollectionViewSource CollectionContext { get; }
}
Dans CollectionPrintContext.cs j'ajouté la propriété suivante pour loger le 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"));
}
}
}
Dans CollectionPrinter.cs, j'ai ensuite modifié CalculateChild. Le nouveau code comporte des commentaires le marquant
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;
}
Dans le fichier cs de mon imprimante, j'ai défini le tri et le regroupement. Une chose à noter est la façon dont je l'ai configuré, cette PageCollectionViewSource sert uniquement de modèle pour le regroupement et le tri. Aucune donnée ne sera stockée dedans.
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();
}
}
Cette classe InvReportData-je utiliser pour compléter les informations dans l'en-tête et pied de page ainsi et il semble que ce
public class InvReportData : IContainsCollectionViewSource
{
public string BoatName { get; set; }
public string ReportTypeLabel { get; set; }
public string Date { get; set; }
public CollectionViewSource PageCollectionSource { get; set; }
}
Et mon code XAML pour les modèles se fixe à la DisplayCollectionViewSource.View au lieu de la propriété 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>
Et le dernier morceau de code que vous aurez besoin de mettre dans la fenêtre/contrôle où l'imprimante sera affiché/imprimé à partir. Ici, vous configurez la CollectionViewSource avec les données et le mettre à 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;
de l'imprimante et ceux-ci devraient être tous les changements que vous devez faire pour obtenir le regroupement de travailler avec datagrids. Prendre plaisir.
Je suis content que vous l'ayez compris, mais s'il vous plaît postez votre solution plutôt que d'y attacher un lien. –