小编gix*_*gix的帖子

在WPF中设置嵌套元素的样式

假设您有一个嵌套的元素结构,例如带有MenuItems的ContextMenu:

<ContextMenu Style="{StaticResource FooMenuStyle}">
    <MenuItem Style="{StaticResource FooMenuItemStyle}"/>
    ...
</ContextMenu>
Run Code Online (Sandbox Code Playgroud)

您可以轻松地将样式或模板应用于ContextMenu或MenuItem元素.但是如果MenuItem样式属于Menu样式,则将它添加到每个MenuItem元素是非常麻烦和冗余的.

有没有办法自动将这些应用于子元素?所以你可以简单地写这个:

<ContextMenu Style="{StaticResource FooMenuStyle}">
    <MenuItem/>
    ...
</ContextMenu>
Run Code Online (Sandbox Code Playgroud)

如果FooMenuStyle可以包含包含MenuItem元素的样式,那将是很好的,但这似乎是不可能的.

编辑:菜单示例可能会产生误导,因为我不知道ItemContainerStyle,并且意图是一般解决方案.基于这两个答案,我提出了两个解决方案:一个常规变体和一个ItemContainerStyle等:

<Style x:Key="FooMenuItem" TargetType="{x:Type MenuItem}">
    ...
</Style>

<Style x:Key="FooMenu" TargetType="{x:Type ContextMenu}">
    <!-- Variant for specific style attribute -->
    <Setter Property="ItemContainerStyle"
            Value="{StaticResource FooMenuItem}"/>

    <!-- General variant -->
    <Style.Resources>
        <Style TargetType="{x:Type MenuItem}"
               BasedOn="{StaticResource FooMenuItem}"/>
    </Style.Resources>
</Style>

<ContextMenu Style="{StaticResource FooMenu}">
    <MenuItem/>
</ContextMenu>
Run Code Online (Sandbox Code Playgroud)

wpf styles children nested

60
推荐指数
3
解决办法
3万
查看次数

使用C#中的枚举索引数组

我有很多固定大小的数字集合,其中每个条目都可以使用常量访问.当然,这似乎指向数组和枚举:

enum StatType {
    Foo = 0,
    Bar
    // ...
}

float[] stats = new float[...];
stats[StatType.Foo] = 1.23f;
Run Code Online (Sandbox Code Playgroud)

这个问题当然是你不能使用枚举来索引没有强制转换的数组(虽然编译的IL使用普通的int).所以你必须在整个地方写这个:

stats[(int)StatType.foo] = 1.23f;
Run Code Online (Sandbox Code Playgroud)

我试图找到方法使用相同的简单语法而不进行强制转换但尚未找到完美的解决方案.使用字典似乎是不可能的,因为我发现它比数组慢大约320倍.我还尝试为枚举作为索引的数组编写泛型类:

public sealed class EnumArray<T>
{
    private T[] array;
    public EnumArray(int size)
    {
        array = new T[size];
    }
    // slow!
    public T this[Enum idx]
    {
        get { return array[(int)(object)idx]; }
        set { array[(int)(object)idx] = value; }
    }
}
Run Code Online (Sandbox Code Playgroud)

甚至是带有指定枚举的第二个通用参数的变体.这非常接近我想要的但问题是你不能只是将一个非特定的枚举(从泛型参数或盒装类型枚举)转换为int.相反,你必须首先使用强制转换为对象然后将其强制转换.这有效,但速度很慢.我发现为索引器生成的IL看起来像这样:

.method public hidebysig specialname instance !T get_Item(!E idx) cil managed
{
    .maxstack 8
    L_0000: ldarg.0 
    L_0001: ldfld !0[] …
Run Code Online (Sandbox Code Playgroud)

c# arrays enums cil

18
推荐指数
3
解决办法
1万
查看次数

单元测试时如何处理在其他线程中引发的异常?

使用Visual Studio Team Test进行测试时,会在结果中捕获并报告测试中未处理的异常.所以我有点惊讶地看到测试托管进程(VSTestHost.exe)崩溃并显示系统崩溃对话框.

经过进一步调查,此崩溃是另一个线程中引发的未处理异常(更直接地,它是异步套接字回调).事实上这样的事情会导致托管过程崩溃:

[TestMethod]
void Test()
{
    new Thread(() => { throw new Exception(); }).Start();
}
Run Code Online (Sandbox Code Playgroud)

有什么建议我应该在那里做什么?

  • 我是否应该忍受它,说任何分发/签入的代码应该至少测试一次,所以这样的事情很可能会被抓住?
  • 我是否应该尝试安装全局异常处理程序并在每个拆除方法中检查其状态?
  • 或者也许已经存在帮助这个的东西?

multithreading unit-testing exception visual-studio

14
推荐指数
1
解决办法
3648
查看次数

如何在MVVM视图模型中指定资源?

假设我想显示每个对象应该具有名称和合适图像的对象列表(例如带有图标的MenuItems,或带有文本和图像的按钮).

所有的实施例和方案在视图模型露出的图像作为到PNG文件的路径,然后结合的SourceImage这一点.但是,如果我想使用矢量图像(例如DrawingImage在本地ResourceDictionary)?从视图模型中公开DrawingImage似乎很糟糕,因为我必须存储对应用程序/窗口/用户控件/ ...的引用(并且建议不要从视图模型中公开这样的XAML对象).

因此,更好的方法是在视图模型中使用字符串标识符,然后以某种方式选择适当的资源.如果该标识符是资源键,则此代码段看起来很诱人,但不起作用:

<Image Source="{StaticResource {Binding Icon}}"/>
Run Code Online (Sandbox Code Playgroud)

我找到了两个解决方法,虽然它们对我不起作用.

  1. 第一个是使用正常绑定到图标的转换器查找资源Application.Current.如果资源存储在我认为的其他地方(并且我最初碰到这个问题的情况没有运行应用程序,因为它是一个Window选择要启动的应用程序!),这不起作用.

  2. 第二种解决方法是使用从传递的绑定StaticResourceExtension中获取的标记扩展派生的标记扩展ResourceKey:

    <Image Source="{local:BindableStaticResource {Binding Icon}"/>
    
    Run Code Online (Sandbox Code Playgroud)

    这个看起来很整洁,因为它可以使用本地资源,也可以用于其他事情.但是在使用它时我总是遇到异常("无法找到名为{FooIcon}的资源.",显示正确的XAML文件和扩展名的位置).即使是从StaticResourceExtension刚刚将资源键传递给基础构造函数的空资源扩展也不起作用,我无法解释原因.只是使用StaticResourceExtension工作得很好.

我有什么想法可以解决第二种方法,甚至是更好的解决方案?

编辑

我注意到它直接使用它确实有效:

<Window>
    <Window.Resources>
        <DrawingImage x:Key="SomeIcon"/>
    </Window.Resources>
    <Image Source="{BindableStaticResource {Binding Icon}}"/>
</Window>
Run Code Online (Sandbox Code Playgroud)

但例如在一个DataTemplate.虽然正常StaticResourceExtension情况下两种情况都有效,但我感到困惑的是出了什么问题.

wpf resources xaml image mvvm

12
推荐指数
1
解决办法
7897
查看次数

如何卸载Win32程序集并清理WinSxS?

经过大量的试验和错误(主要是由于缺少文档和示例),我设法创建了MSI安装程序,将自定义DLL作为并行程序集安装到WinSxS.只有一个问题:卸载会将所有文件(DLL,清单和目录)保留在WinSxS目录中.怎么能或者我应该最好地清理它?我确信没有别的东西可以引用它.

我已经读过某个地方,WinSxS有一个自我清理过程,随着时间的推移清理,但我无法找到更多相关信息.你可以手动调用它来清理东西吗?

我看到的唯一另一种方法是手动删除这些位.首先,您必须将所有文件(程序集,目录,清单及其各自的目录)的所有者从SYSTEM更改为管理员帐户,调整权限并将其删除.注册表中还有一些部分(我认为HKLM\COMPONENTS\DerivedData\Components可能是一个地方),但由于WinSxS应该被视为不透明,因此很难找到任何信息.

windows-installer winsxs assemblies wix uninstall

11
推荐指数
2
解决办法
2万
查看次数

在Windows网络中启动远程进程

我有几台从机和一台主机一起运行分布式应用程序.每台从属机器上的进程必须具有GUI和网络访问权限(我认为它将被称为交互式进程).为了便于使用,如果主机可以启动/停止这些从机上的进程,那将是很好的.

我的第一个想法是使用WMI和Win32_Process类来启动远程进程,但经过进一步调查后发现,以这种方式启动的进程是非交互式和隔离的,因此不能有任何GUI.一个注释说可以使用Win32_ScheduledJob.Create创建一个远程交互式进程,但它在LocalSystem帐户下运行,我想避免(我甚至无法让它正常运行).

什么是解决这个问题的好方法?也许有可能启动一个帮助应用程序,这反过来启动一个正确的过程,但这似乎很脏.

编辑:当我尝试它时,PsExec非常笨重,并且慢慢地(不知道为什么).进一步看看PsExec,它似乎在远程机器上安装了一个临时服务来启动应用程序.这是使用适当身份产生交互式流程的唯一方法吗?我应该在节点的设置中包含帮助程序服务吗?但即便如此,我将如何与之沟通呢?

windows networking distributed cluster-computing remote-process

7
推荐指数
1
解决办法
1万
查看次数

如何调整WPF窗口的大小"滞后"?

我在WPF世界中相对较新,我立即注意到的一件事是当你调整窗口大小时窗口内容的绘制有多么迟钝.例如,如果窗口边缘有滚动条,那么这些滚动条在缩小时将被部分隐藏,并且在放大时它们与窗口边界之间有空间.

这甚至发生在Visual Studio中创建的空WPF项目中.更糟糕的是它也发生在背景中,你可以看到窗口后面的东西(其他窗户,桌面壁纸等)在放大时泄漏.

起初我认为这是WPF的一个丑陋限制,看到本机或WinForms应用程序调整得很好(如果写得正确).但是当我看到Expression Blend时,窗口背景保持不透明(尽管窗口内容仍然落后).他们如何防止所描述的问题,是否有任何方法可以改进调整大小以更接近原生/ WinForm GUI?

wpf optimization xaml resize window

6
推荐指数
1
解决办法
3414
查看次数

为不存在的文件创建 IShellItem 实例

如何为不存在的文件(或目录)获取IShellItem对象?

首先我认为这可能是不可能的,但例如IFileSaveDialogIShellItem为其结果创建了这样的一个(如果您在对话框中指定一个新文件)。

windows com winapi windows-shell

6
推荐指数
1
解决办法
2747
查看次数

如何将可编辑的ComboBox添加到Vista的Common Item Dialog?

Vista推出了新的Common Item Dialogs,用于打开和保存取代旧的Common File Dialogs的文件.可以使用简单的IFileDialogCustomize接口添加自定义控件.其中一个ComboBox是不可编辑的标准.有没有办法创建可编辑的ComboBox或修改现有的(通过添加CBS_DROPDOWN样式)?

com winapi combobox windows-vista

5
推荐指数
1
解决办法
423
查看次数