更新:我已向Microsoft Connect 提交了错误报告,请投票支持!
更新2: Microsoft已将错误报告标记为已修复
微软于18/08/2010 17:25发表
此错误将在运行时的未来版本中修复.我担心现在判断它是在服务包还是下一个主要版本中还为时过早.
自从升级到VS2010后,我的'is'关键字出现了一些非常奇怪的行为.
下面的程序(test.cs)在调试模式下编译时(对于x86)输出True,在编译时使用优化(对于x86)时输出False.编译x64或AnyCPU中的所有组合可得到预期结果True.
.NET 3.5下的所有编译组合都给出了预期的结果True.
我正在使用下面的批处理文件(runtest.bat)来编译和测试代码,使用编译器.NET框架的各种组合.
using System;
public class Program
{
public static bool IsGuid(object item)
{
return item is Guid;
}
public static void Main()
{
Console.Write(IsGuid(Guid.NewGuid()));
}
}
Run Code Online (Sandbox Code Playgroud)
@echo off
rem Usage:
rem runtest -- runs with csc.exe x86 .NET 4.0
rem runtest 64 -- runs with csc.exe x64 .NET 4.0
rem runtest v3.5 -- runs with csc.exe …
Run Code Online (Sandbox Code Playgroud) 我通过该ApplicationHost.CreateApplicationHost
方法托管ASP.NET运行时.当我修改web.config
应用程序运行时,我看到很多第一次机会ThreadAbortException
抛出.这是在我的应用程序崩溃之前.我假设这是因为运行时已检测到配置更改并想要重新启动.
这对我们来说并不是真正受支持的场景,所以我更愿意,如果我可以关闭自动重新加载.
有谁知道如何做到这一点?
我们的域模型中有许多不可变值对象,其中一个例子是位置,由纬度,经度和高度定义.
/// <remarks>When I grow up I want to be an F# record.</remarks>
public class Position
{
public double Latitude
{
get;
private set;
}
// snip
public Position(double latitude, double longitude, double height)
{
Latitude = latitude;
// snip
}
}
Run Code Online (Sandbox Code Playgroud)
允许编辑位置的显而易见的方法是构建具有getter 和 setter 的ViewModel ,以及提取经验证的不可变位置实例的ToPosition()方法.虽然这个解决方案没问题,但它会产生大量重复的代码,尤其是XAML.
有问题的值对象包含三到五个属性,这些属性通常是X,Y,Z和一些辅助内容的变体.鉴于此,我考虑创建三个ViewModel来处理各种可能性,其中每个ViewModel需要公开每个属性的值的属性以及为每个标签显示的描述(例如"Latitude").
更进一步,似乎我可以将它简化为一个可以处理N个属性并使用反射挂钩所有内容的一般ViewModel.像属性网格,但对于不可变对象.属性网格的一个问题是我希望能够更改外观,以便我可以使用标签和文本框,例如:
Latitude: [ 32 ] <- TextBox
Longitude: [ 115 ]
Height: [ 12 ]
Run Code Online (Sandbox Code Playgroud)
或者将它放在DataGrid中,例如:
Latitude | Longitude | Height
32 115 12
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:
你能想出一个解决这个问题的优雅方法吗?有没有这样做的图书馆或关于类似的东西的文章?
我主要是在寻找:
我有一个包含许多行和列的WPF网格,它们都包含TextBlocks和TextBoxes之类的东西.
对于这种特定情况,我希望第1列中的所有内容都有填充,第2列中的所有内容都要对齐.看起来非常非WPF,必须在网格中的每个项目上设置这些属性.
我知道我可以通过这样的方式为网格中的所有TextBlock创建一个样式:
<Grid>
<Grid.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="HorizontalAlignment" Value="Right"/>
</Style>
</Grid.Resources>
</Grid>
Run Code Online (Sandbox Code Playgroud)
但有没有办法将该样式仅应用于第2列中的控件?
我应该使用不同的控件吗?
我正在使用第三方库将图像渲染到GDI DC,我需要确保在没有任何平滑/抗锯齿的情况下渲染任何文本,以便我可以将图像转换为带有索引颜色的预定义调色板.
我用于渲染的第三方库不支持这个,只是根据字体渲染的当前窗口设置呈现文本.他们还表示他们不太可能在短时间内添加切换抗锯齿功能.
到目前为止,我发现的最好的工作是以这种方式调用第三方库(为简洁起见,省略了错误处理和先前的设置检查):
private static void SetFontSmoothing(bool enabled)
{
int pv = 0;
SystemParametersInfo(Spi.SetFontSmoothing, enabled ? 1 : 0, ref pv, Spif.None);
}
// snip
Graphics graphics = Graphics.FromImage(bitmap)
IntPtr deviceContext = graphics.GetHdc();
SetFontSmoothing(false);
thirdPartyComponent.Render(deviceContext);
SetFontSmoothing(true);
Run Code Online (Sandbox Code Playgroud)
这显然对操作系统产生了可怕的影响,每次我渲染图像时,其他应用程序都会从禁用的cleartype闪烁到禁用和返回.
所以问题是,有没有人知道如何改变特定DC的字体渲染设置?
即使我可以只进行更改过程或线程而不是影响整个操作系统,这将是向前迈出的一大步!(这样我就可以选择将这个渲染转换为一个单独的进程 - 无论如何都会在渲染后将结果写入磁盘)
编辑:我想补充一点,我不介意解决方案是否比一些API调用更复杂.我甚至会对一个解决方案感到满意,如果它只用了一天工作就会挂钩系统dll.
编辑:背景信息 第三方库使用约70种颜色的调色板渲染.在将图像(实际上是地图图块)渲染到DC之后,我将每个像素从其32位颜色转换回其调色板索引,并将结果存储为8bpp灰度图像.这将作为纹理上传到视频卡.在渲染过程中,我重新应用了调色板(也存储为纹理),并在视频卡上执行了像素着色器.这允许我立即在不同的调色板之间切换和淡入淡出,而不需要重新生成所有需要的切片.生成并上传所有瓷砖需要10-60秒才能获得典型的世界观.
编辑:将GraphicsDevice重命名为图形 此问题的先前版本中的GraphicsDevice类实际上是System.Drawing.Graphics.我重命名了它(使用GraphicsDevice = ...),因为有问题的代码在命名空间MyCompany.Graphics中,编译器无法正确解析它.
编辑:成功!
我甚至设法将PatchIat
下面的函数移植到C#的帮助下Marshal.GetFunctionPointerForDelegate
..NET互操作团队确实做得非常出色!我现在使用以下语法,其中Patch
是一个扩展方法System.Diagnostics.ProcessModule
:
module.Patch(
"Gdi32.dll",
"CreateFontIndirectA",
(CreateFontIndirectA original) => font =>
{
font->lfQuality = NONANTIALIASED_QUALITY;
return original(font);
});
private unsafe delegate …
Run Code Online (Sandbox Code Playgroud) 我刚刚开始使用WPF中的MVVM模式,我认为构建代码的最优雅方法是将视图模型注入到视图的构造函数中.
这一切都很好,但ReSharper在XAML中发出警告,我的视图没有默认构造函数.我假设这样我可以在XAML中根据需要构建我的视图,但这只是猜测.
通过要求我的视图在构造函数中采用视图模型,我放弃了什么?
编辑:我的视图构造函数如下所示:
public ExampleView(ExampleViewModel viewModel)
{
if (viewModel == null) throw new ArgumentNullException("viewModel");
DataContext = viewModel;
}
Run Code Online (Sandbox Code Playgroud)
答:我选择了以下设置,其中DesignTime命名空间包含用于测试和设计时支持的ViewModel的模拟版本.
ExampleView.xaml.cs
public ExampleView()
{
InitializeComponent();
}
public ExampleView(IExampleViewModel viewModel)
: this()
{
DataContext = viewModel;
}
Run Code Online (Sandbox Code Playgroud)
ExampleView.xaml
<UserControl
x:Class="Wpf.Examples.ExampleView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:DesignTime="clr-namespace:Wpf.Examples.DesignTime">
<UserControl.DataContext>
<DesignTime:ExampleViewModel/>
</UserControl.DataContext>
</UserControl>
Run Code Online (Sandbox Code Playgroud) 而不是使用这样的界面:
public interface IStartable
{
void Start();
void Stop();
}
Run Code Online (Sandbox Code Playgroud)
我通常只是使对象的构造函数运行Start()代码,并实现IDisposable,以便dispose方法运行Stop()代码.
这只是风格问题吗?或者我没有像IStartable这样的东西错过了一些重要的东西?我所看到的只是额外的复杂性,因为你必须保持它的启动/停止状态.
使用启动/停止与使用ctor/dispose的优缺点是什么,特别是在IoC/DI容器的上下文中?
编辑:很好的答案,你已经说服我使用一个可启动对象的界面.我无法确定谁的答案是最好的,所以我会接受24小时后得票最多的人.
oop dependency-injection inversion-of-control object-lifetime
wpf ×3
c# ×2
asp.net ×1
casting ×1
cleartype ×1
gdi ×1
grid ×1
hook ×1
httpruntime ×1
iis ×1
immutability ×1
mvvm ×1
oop ×1
optimization ×1
recycle ×1
struct ×1
web-config ×1
winapi ×1