WPF与弹出窗口的对决

Tra*_*den 17 .net wpf xaml tooltip windows-8

我刚刚从Windows 7将我的PC移动到Windows 8,在运行我们的WPF应用程序时,我注意到我们的WPF弹出窗口和/或工具提示现在默认情况下位于左下角,而不是正常的右下角.有没有人注意到这个?我知道你可以在xaml的每个工具提示中指定它们的位置,但我们有很多工具提示和弹出窗口.我想知道是否有办法在WPF应用程序中全局指定默认位置.谷歌在这个问题上没有取得很多成果.我们有理由将它们保持在相同的原始默认位置(某些弹出窗口具有相对于其启动位置的内容).

Windows 8 :(左下)

Win8上的工具提示

Windows 7 :(右下)

Win7上的工具提示

相同的代码!标准的"工具提示"xaml属性.

有任何想法吗?

已经解决,我发表了评论


好的,我发现了这个问题.它与平板电脑/触摸屏有关.(左撇子...右手偏好)这另一个链接提供了一个原因.我正在制定一个解决方案来解决这个问题.生病了很快就会发布!

Windows 8弹出位置

小智 20

感谢@TravisWhidden提供的解决方案.刚刚实现了一个侦听StaticPropertyChanged事件的改进版本,我将它粘贴在这里,因为它似乎不是一个"黑客".

    private static readonly FieldInfo _menuDropAlignmentField;
    static MainWindow()
    {
        _menuDropAlignmentField = typeof(SystemParameters).GetField("_menuDropAlignment", BindingFlags.NonPublic | BindingFlags.Static);
        System.Diagnostics.Debug.Assert(_menuDropAlignmentField != null);

        EnsureStandardPopupAlignment();
        SystemParameters.StaticPropertyChanged += SystemParameters_StaticPropertyChanged;
    }

    private static void SystemParameters_StaticPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        EnsureStandardPopupAlignment();
    }

    private static void EnsureStandardPopupAlignment()
    {
        if (SystemParameters.MenuDropAlignment && _menuDropAlignmentField != null)
        {
            _menuDropAlignmentField.SetValue(null, false);
        }
    }
Run Code Online (Sandbox Code Playgroud)


Tra*_*den 11

好吧,对于那些不希望在他们的应用程序中发生这种情况的人(这是我们的愿望),我们为WPF创建了一个不错的小黑客.这对我们很有用.

第一:

此代码将运行解决问题的代码:

public static void SetAlignment()
{
    var ifLeft = SystemParameters.MenuDropAlignment;

    if (ifLeft)
    {
        // change to false
        var t = typeof(SystemParameters);
        var field = t.GetField("_menuDropAlignment", BindingFlags.NonPublic | BindingFlags.Static);
        field.SetValue(null, false);

        ifLeft = SystemParameters.MenuDropAlignment;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,环境可以对这些值的微软内部缓存进行去验证,因此我们必须挂钩到WinProc才能得到这个值.我不会发布WinProc代码,只发布所需的消息:

这些是将取消验证内部缓存的Win32消息:

private const int WM_WININICHANGE = 0x001A;
private const int WM_DEVICECHANGE = 0x219;
private const int WM_DISPLAYCHANGE = 0x7E;
private const int WM_THEMECHANGED = 0x031A;
private const int WM_SYSCOLORCHANGE = 0x15;
Run Code Online (Sandbox Code Playgroud)

快速的snippit将重新设定你的偏好.因为我们被挂钩到WinProc,所以你需要在WinProc完成其他处理程序上的消息后更改此值.我们有延迟将偏好值重新设置为我们想要的值.

if (msg == WM_WININICHANGE || msg == WM_DEVICECHANGE || msg == WM_DISPLAYCHANGE || msg == WM_THEMECHANGED || msg == WM_SYSCOLORCHANGE)
{
    Timer timer = null;
    timer = new Timer((x) =>
        {
            WpfHelperHacks.SetAlignment();
            timer.Dispose();
        },null, TimeSpan.FromMilliseconds(2), TimeSpan.FromMilliseconds(-1));
}
Run Code Online (Sandbox Code Playgroud)

就像它的完整.我希望这有助于其他人!