我们有一个相当大的WPF业务应用程序,我正在研究现有的WPF FixedPage/FixedDocument报告的重组.
这是一个有点繁忙的生态系统.我们有一个内置的表单生成器,你可以使用许多不同的控件(就像一个迷你内置的可视化工作室).一切正常.您在屏幕上填写表格,然后您可以打印(到XPS)相同的副本到标准8.5x11纸张.
在代码中,我们将此报告分解为垂直块.假设每张纸块在打印的纸上都是一英寸或两英寸高.这就是我们处理分页的方式.如果下一个块对于页面太高,我们执行NewPage()并重复.正如我所提到的,这很好.
WPF有一个巨大的学习曲线,我一直在回顾旧代码和重构事物,并愉快地使用DataTemplates,强类型ViewModels和通用ContentControls来减少代码的大小.屏幕上的表单生成器仍然有效,但FixedDocument报告已经变得奇怪了.
回到那些垂直切片,我们将用户的表单打印为纸张作为单独的网格控件.没有什么花哨.每个网格(如上所述)可能是一英寸或两英寸高,包含复选框,单选按钮,文本块等的任意随机混合.
当网格包含这些库存(标准)MS WPF控件时,我可以整天这样做:
System.Windows.Controls.Grid g = .....
g.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
g.Arrange(new Rect(g.DesiredSize));
Run Code Online (Sandbox Code Playgroud)
并获得适当的尺寸,即100 x 67.
现在,有时网格只有一个控件 - 如果你愿意的话就是一个标题(即"本月的时间表").添加到该网格的唯一子控件是ContentControl.
ContentControl只是绑定到ViewModel:
<ContentControl Content="{Binding}" />
Run Code Online (Sandbox Code Playgroud)
然后在资源字典中有两个DataTemplates来获取这个绑定.在这里,我将展示:
<UserControl.Resources>
<w:MarginConverter x:Key="boilerMargin" />
<DataTemplate DataType="{x:Type render:BoilerViewModel}">
<render:RtfViewer
Width="{Binding Path=Width}"
TextRTF="{Binding Path=Rtf}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type render:Qst2NodeViewModel}">
<ContentControl Content="{Binding Path=BoilerVm}">
<ContentControl.Margin>
<MultiBinding Converter="{StaticResource boilerMargin}">
<Binding Path="NodeCaptionVm.Height" />
<Binding Path="NodeLeft" />
</MultiBinding>
</ContentControl.Margin>
</ContentControl>
</DataTemplate>
</UserControl.Resources>
Run Code Online (Sandbox Code Playgroud)
ContentControl将获取最底部的datatemplate.然后该模板将使用上面较小的模板.
花式转换器只是设置了一个余量.阅读可能很难看,但这一切都在父用户控件的屏幕上正确显示.它的大小和理由都是正确的.
在打印报告方面(XPS),我必须在代码中创建这些控件并测量它们以查看它们是否适合当前的FixedPage.当我去做这一步时:(在包含此ContentControl的网格上)
g.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
g.Arrange(new Rect(g.DesiredSize));
Run Code Online (Sandbox Code Playgroud)
我回到0,0大小.即使它应该像730x27一样.再次,在屏幕上,托管在UserControl中,这一切都很好.只是尝试实例化它并纯粹在代码中测量它失败了.我已经确认控件已添加到网格中,其行和列集已添加到Children集合中,等等...
如果我使用UpdateLayout调用添加这两个语句,就像这样,那么它的工作原理如下:
g.UpdateLayout(); //this fixes it
g.Measure(new Size(double.PositiveInfinity, …Run Code Online (Sandbox Code Playgroud) 我是xcode/iOS/Objective-C和sqlite的新手.我正在尝试自学基础知识 - 我想使用sqlite3包装器"sqlite3_exec"进行选择查询.出于某种原因,我找不到任何人这样做的简单例子.
基本上,该方法有一个回调函数的参数(第三个):
int sqlite3_exec(
sqlite3*, /* An open database */
const char *sql, /* SQL to be evaluated */
int (*callback)(void*,int,char**,char**), /* Callback function */
void *, /* 1st argument to callback */
char **errmsg /* Error msg written here */
);
Run Code Online (Sandbox Code Playgroud)
没关系.我对回调并不陌生.但是,我似乎无法正确地获得语法.我接管了我的iPad(iOS 5.1)xcode(4.3)项目中的一个视图控制器,并进行了如下所示的更改:
#import "SecondViewController.h"
#import "sqlite3.h"
#import "AppState.h"
@interface SecondViewController ()
@end
@implementation SecondViewController
- (int)myCallback:(void *)a_parm argc:(int)argc argv:(char **)argv column:(char **)column
{
return 0;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup …Run Code Online (Sandbox Code Playgroud)