在WinForms MDI应用程序中托管WPF用户控件时,如果您有多个彼此重叠的表单会导致非常不同的可视化工件,则会出现绘图问题.将一个子窗体拖动到另一个子窗体之后,这些工件主要是可见的,这些窗体也承载WPF内容,或者允许子窗体的边缘在拖动它时由主MDI父窗体剪切.在完成子窗体的拖放操作后,工件一般会保持不变,但我发现将焦点设置到不同的应用程序窗口,然后重新聚焦到我的应用程序窗口,它重新绘制,并且一切都很好,直到孩子表格再次移动.请参阅下面的图片来说明问题.

那些在微软的人坚持认为WinForms MDI已经是MDI的充分解决方案,并且不需要重新发明WPF,尽管我发现很难相信他们尝试以这种方式创建WPF应用程序,因为它有明显的缺点.
更新:我遗漏的一些额外注释是,如果我创建这些表单而不设置MdiParent,它们将被创建为常规表单,并且不会发生此问题.此问题似乎是WinForms MDI方案所特有的.此外,我目前在Windows 7企业版上运行,我知道在Windows XP上结果可能会有很大差异,但我无法对此进行测试.
更新:我在这个问题上找到了一些我认为应该分享的其他相关资源.
我有一个自定义的 SplitButton 实现,其中包含一个 ComboBox,其中有多个绑定到命令的 ComboBoxItem。我可以很好地绑定到命令的 Name 和 Text 属性,但无法将 ComboBoxItem 的IsEnabled属性绑定到 Command 的CanExecute方法的结果,因为它是一个方法。是否有一些我不知道的用于绑定到方法的语法,或者是否有一些技巧可以帮助我绑定到 CanExecute。
顺便说一句,我考虑过使用自定义 ValueConverter,除了我意识到重新评估 CanExecute 时我可能不会收到任何更新,因为它不是属性,而且我的命令不是业务对象。在我看来,此时我可能必须为命令创建一个 ViewModel,以便仅在我的自定义 SplitButton 控件中使用,但这对我来说似乎有点过分了。
在焦距和键盘导航方面,我看到了奇怪的行为.在下面的示例中,我有一个简化的ItemsControl,它已经模板化,因此它显示了一个绑定到ItemsSource的CheckBoxes列表.
<ItemsControl FocusManager.IsFocusScope="True"
ItemsSource="{Binding ElementName=TheWindow, Path=ListOStrings}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Run Code Online (Sandbox Code Playgroud)
由于某些奇怪的原因,FocusManager.IsFocusScope ="True"分配导致在通过鼠标单击选中复选框时无法设置键盘焦点,并且当使用空格键选中复选框时,焦点将跳出ItemsControl.键盘.这两个症状似乎都指向选中复选框时发生的一些奇怪的导航,但我很难找到它的底部.
如果我使用此方法将可视树中的任何父元素设置为焦点范围,则会出现此问题.如果我删除了FocusManager.IsFocusScope ="True",那么问题就会消失.不幸的是,我在一个更大的项目中看到了这个问题,我不能仅仅删除这些焦点范围而不必担心其他与焦点相关的后果.
有人可以向我解释我所看到的奇怪行为吗?这是一个错误还是我完全错过了什么?
我有一种情况,我使用NetDataContractSerializer序列化一些.NET对象,并将XML存储在数据库中,以此来记住应用程序中这些对象的状态.最近我遇到了第一种情况,其中一些代码重构属性和类型名称导致无法反序列化此XML数据.
到目前为止,我已经提出了两种不同的攻击计划,用于处理版本兼容性中断,例如使用NetDataContractSerializer本身可用的工具来控制反序列化或直接转换XML.从我的实验和研究看来,可以使用自定义SerializationBinder将其反序列化为不同的类型,并且可以通过实现ISerializable或通过实现ISurrogateSelector和ISerializationSurrogate来编写序列化代理来解决属性名称/类型更改.不幸的是,这个首选机制还没有完成,除非我可以显示,否则看起来使用代理商在NetDataContractSerializer上无法在序列化数据的版本之间移动,这是由于微软的一些无法解释的设计决定.Microsoft提出的建议是在双方使用相同的序列化,这完全违背了使用代理的目的,以便在类型名称更改或移动到不同的命名空间或程序集中时提供帮助.
要修复它,请使用相同的NetDataContractSerializer实例或另一个也使用兼容的SurrogateSelector初始化的实例.
这个解释与MSDN文章冲突,该文章说明了如何使用自定义绑定器替换类型以及处理序列化结构中的其他更改.
在反序列化期间,格式化程序看到已设置了活页夹.当每个对象即将被反序列化时,格式化程序调用绑定器的BindToType方法,向其传递格式化程序要反序列化的程序集名称和类型.此时,BindToType决定实际构造的类型并返回此类型.
请注意,如果新类型通过Serializable自定义属性使用简单序列化,则原始类型和新类型必须具有相同的确切字段名称和类型.但是,该类型的新版本可以实现ISerializable接口,然后将调用其特殊构造函数,该类型可以检查SerializationInfo对象中的值并确定如何反序列化自身.
因此,要么我能够让NetDataContractSerializer将我的V1 XML反序列化为我的V2类型,要么我将不得不手动转换XML.如果有人能够证明NetDataContractSerializer的SerializationInfo确实在使用ISerializable或使用序列化代理时确实有效,或者至少提供比Microsoft给出的更好的解释,否则我可能会发布一个新问题来讨论最好的方法在.NET中直接转换旧的XML.
更新2011-08-16: 经过一些实验,似乎ISerializable和序列化代理技术都可以正常工作,如果序列化的原始类型实现ISerializable,否则如果类型只使用[Serializable]属性,它会出现在对象中的每个字段图形以额外属性的形式缺少一些有价值的类型信息.
使用[Serializable]属性的示例
<OldClass2 xmlns:i="http://www.w3.org/2001/XMLSchema-instance" z:Id="1" z:Type="NdcsSurrogateTest.OldClass2" z:Assembly="NdcsSurrogateTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" xmlns="http://schemas.datacontract.org/2004/07/NdcsSurrogateTest">
<_stable z:Id="2">Remains the same</_stable>
<_x003C_OldProperty_x003E_k__BackingField>23</_x003C_OldProperty_x003E_k__BackingField>
</OldClass2>
Run Code Online (Sandbox Code Playgroud)
实现ISerialzable的示例:
<OldClass2 xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:x="http://www.w3.org/2001/XMLSchema" z:Id="1" z:Type="NdcsSurrogateTest.OldClass2" z:Assembly="NdcsSurrogateTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" xmlns="http://schemas.datacontract.org/2004/07/NdcsSurrogateTest">
<_stable z:Id="2" z:Type="System.String" z:Assembly="0" xmlns="">Remains the same</_stable>
<_x003C_OldProperty_x003E_k__BackingField z:Id="3" z:Type="System.Int32" z:Assembly="0" xmlns="">23</_x003C_OldProperty_x003E_k__BackingField>
</OldClass2>
Run Code Online (Sandbox Code Playgroud)
当使用带有自定义绑定器的NetDataContractSerializer反序列化第一个示例以更改类型,然后在该类型上实现ISerializable或提供指定基本上满足ISerializalbe角色的序列化代理的代理选择器时,您将在ISerializationSurrogate中看到一个空的SerializationInfo .SetObjectData方法.在第二个示例中处理xml时,SerializationInfo似乎可以获得正确的信息,并且按预期工作.
我的结论是NetDataContractSerializer为仅支持通过SerializableAttribute进行序列化的类型生成的默认XML与使用ISerializable或序列化代理技术的反序列化不兼容,因为缺少类型信息.因此,为了使NetDataContractSerializable更具未来性,可以自定义序列化以确保XML中包含此类型信息,以便可以自定义以后的反序列化,而无需手动转换源XML.
我有一个使用 Gradle 作为构建工具的简单 Java 应用程序。通常,当我使用 grade 运行我的应用程序时,我会设置一个特定的环境变量set MYVAR=myval,然后我的应用程序使用这个值。当我在 IntelliJ 中设置运行/调试基于 Gradle 的应用程序的配置时一切顺利,只是我无法找到指定环境变量 MYVAR 的方法,因此它始终未设置。
两个多小时以来,我一直在阅读各种文档和文章中的选项,但一无所获。
我正在使用webpack,并分别根据whatwg-fetch和es6-promise软件包跟踪示例到polyfill fetch和旧版浏览器的Promise.
new webpack.ProvidePlugin({
'fetch': 'imports?this=>global!exports?global.fetch!whatwg-fetch',
'Promise': 'exports?global.Promise!es6-promise'
}),
Run Code Online (Sandbox Code Playgroud)
这一切都有意义,但现在我需要polyfill Array.prototype.find(),但无法找到如何使用webpack的ProvidePlugin功能实现这一点.使find变得不同的是它本质上是一个Array原型的方法,我没有找到任何使用ProvidePlugin指定这些东西的例子.有没有人使用webpack来填充像这样的ES6阵列函数?有关如何实现这一目标的任何指示?我是否采用了错误/过时的方式或是否有更好的方法来实现我的需求?
到目前为止,我已经尝试使用paulmillr的polyfill 包来试验语法,但是使用ProvidePlugin并没有成功使用它.
对此进行更多研究使我得到了babel polyfill.而这些资源:
我在这里也发现了babel-polyfill中缺少window.fetch polyfill,这解释了为什么它可能经常是由ProvidePlugin处理的特殊情况.我也在拼凑说,ProvidePlugin更像是一种便利工具而不是应用polyfill的通用工具.直接导入babel-polyfill并删除Promise和其他ES6 pollyfill除了fetch之外,在我的实验中到目前为止看起来有点大有希望.
为了解决来自Redux的警告背后的问题,我偶然发现了一些建议,这些建议解释了在使用React或Redux生成为生产使用而优化的构建时,环境是必要的步骤.Envifying被解释为替换节点特定环境变量的过程,例如process.env.NODE_ENV用实际值替换'production'.
接受这种环境是必要的并且上面的解释是正确的,它让我感到困惑,因为它似乎假设客户端库(如React和Redux)将包含特定于节点的环境变量.是的,我知道这些库特别适合构建同构/通用JavaScript应用程序,但会发现令人惊讶.我是否理解正确?如果是这样,我需要知道在process.env.NODE_ENV节点外使用的模式的解释吗?
如果我理解正确的建议,它会建议如果我使用Webpack,我可能想要使用DefinePlugin像这样的插件.
new webpack.DefinePlugin({
"process.env.NODE_ENV": process.env.NODE_ENV,
}),
Run Code Online (Sandbox Code Playgroud)
这似乎也要求我将NODE_ENV变量设置为我想为我的客户端代码生成的构建的目标环境.这是非常奇怪的,因为我在构建服务器上设置了一个环境变量,以反映在部署到的服务器上运行实际代码的环境.
这一切让我觉得我在一般模式方面缺少一些东西.
相关信息:
我在一个Node应用程序中使用这个ES6 Promise最终实现名为promise.prototype.finally,我希望将其转换为TypeScript,但是我可以在DefinitelyTyped上找到此类包的可用类型.在这些情况下,我只为我需要的功能子集编写了自己的即兴类型定义,但在这种情况下,它是一个修改Promise对象原型的库,我没有遇到任何传统方式来表示这个在TypeScript中.有任何想法吗?
可能相关:
我想知道在使用 TypeScript 时是否有任何工具或技术用于对对象数据进行低级验证。一个示例是 HTTP 服务上的 POST 请求的 JSON 正文。通常,我会为预期数据创建一个接口,然后将数据转换到该接口,但我知道这很肤浅。
例子:
router.route('/supercres')
.get((req, res, next) => {
const typedBody = <SuperCresBody>req.body;
})
interface SuperCresBody {
name: string,
yoyo: boolean,
}
Run Code Online (Sandbox Code Playgroud)
强制执行接口的问题在于 TypeScript 只是一个编译时概念,在运行时不会强制执行任何内容。知道这一点,我很好奇是否有人找到了一种不需要大量样板或工具的聪明方法,以便在运行时完成这些事情的类型检查,而不必将接口契约作为一组命令性检查作为验证步骤来重复。
与此相关的一点是,在最新一集的 Function Geekery中,Matthias Felleisen 在该集末尾附近解释了 Typed Racket 中的类似需求。
相关阅读:
[Writing Templates] 下的主要文档提供了以下用于绑定事件处理程序的示例lit-html。
html`<button @click=${(e) => console.log('clicked')}>Click Me</button>`
Run Code Online (Sandbox Code Playgroud)
添加这个带有默认值render和html函数导入并调用渲染的简单页面,但是似乎没有渲染按钮。如果删除@click事件绑定,则呈现按钮。一定有我遗漏的东西或库中的严重错误。
版本:0.10.2
以下链接与事件处理程序绑定的工作方式有关lit-html:
wpf ×3
typescript ×2
webpack ×2
.net ×1
arrays ×1
data-binding ×1
ecmascript-6 ×1
envify ×1
es6-promise ×1
focus ×1
gradle ×1
isenabled ×1
itemscontrol ×1
itemtemplate ×1
javascript ×1
lit-html ×1
mdi ×1
node.js ×1
polyfills ×1
redux ×1
xaml ×1