在运行时更改窗口样式适用于 VS2008,不适用于 VS2010

发布于 2024-12-04 20:01:49 字数 3282 浏览 1 评论 0原文

在 VS2008(框架 3.5)上工作的东西似乎在 VS2010(框架 4)上不起作用。

我需要在运行时更改窗口的样式(用户首选项)。 在 VS2008 中,此代码有效:

Window1.xaml

<Window x:Class="StyleTest.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        ResizeMode="CanResizeWithGrip">

  <Window.Style>
    <Style TargetType="{x:Type Window}">
      <Setter Property="MinWidth" Value="400" />
      <Setter Property="Width" Value="500" />
      <Setter Property="MinHeight" Value="400" />
      <Setter Property="SizeToContent" Value="Height" />
    </Style>
  </Window.Style>

  <Grid>

  </Grid>
</Window>

Window1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml;
using System.Windows.Markup;
using System.IO;

namespace StyleTest
{
  /// <summary>
  /// Interaction logic for Window1.xaml
  /// </summary>
  public partial class Window1 : Window
  {
    public Window1()
    {
      InitializeComponent();

      Loaded += new RoutedEventHandler(ObjDialog_Loaded);
    }

    void ObjDialog_Loaded(object sender, RoutedEventArgs e)
    {
      XmlDocumentFragment frag = new XmlDocument().CreateDocumentFragment();
      frag.InnerXml = "<Style TargetType=\"{x:Type Window}\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"> " +
                      "  <Setter Property=\"Height\" Value=\"200\" />" +
                      "  <Setter Property=\"Width\" Value=\"200\" />" +
                      "</Style>";
      XmlNode node = frag.FirstChild as XmlElement;

      Style style = LoadXaml(node.OuterXml) as Style;
      if (style != null)
        Style = style;

      UpdateLayout();
    }

    private object LoadXaml(string xaml)
    {
      Exception ex = null;
      object o = LoadXaml(xaml, out ex);

      if (ex != null)
        throw ex;

      return o;
    }

    public static object LoadXaml(string xaml, out Exception exception)
    {
      try {
        ParserContext pc = new ParserContext();
        pc.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
        pc.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
        pc.XmlnsDictionary.Add("l", "http://www.teradp.com/schemas/GN4/1/WinUI");
        pc.XmlnsDictionary.Add("c", "clr-namespace:TeraDP.GN4.Common;assembly=Common");

        exception = null;
        return XamlReader.Load(new MemoryStream(Encoding.UTF8.GetBytes(xaml)), pc);
      }
      catch (Exception ex) {
        exception = ex;
      }

      return null;
    }

  }
}

当我在 Framework 3.5 上运行此代码时,窗口显示的大小为 200x200。 当我在 Framework 4 上运行此代码时,窗口显示的大小为 500x400

最奇怪的是,如果我将 MinWidth 和 MinHeight 添加到运行时应用的样式中,这些属性在 VS2010 中也能正常工作,而 Width 和 Height 似乎被忽略。

有人有解决这个问题的办法吗?

Something that was working on VS2008 (framework 3.5) seems to not work on VS2010 (framework 4).

I need to change the style of a window at runtime (user preference).
In VS2008 this code was working:

Window1.xaml

<Window x:Class="StyleTest.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        ResizeMode="CanResizeWithGrip">

  <Window.Style>
    <Style TargetType="{x:Type Window}">
      <Setter Property="MinWidth" Value="400" />
      <Setter Property="Width" Value="500" />
      <Setter Property="MinHeight" Value="400" />
      <Setter Property="SizeToContent" Value="Height" />
    </Style>
  </Window.Style>

  <Grid>

  </Grid>
</Window>

Window1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml;
using System.Windows.Markup;
using System.IO;

namespace StyleTest
{
  /// <summary>
  /// Interaction logic for Window1.xaml
  /// </summary>
  public partial class Window1 : Window
  {
    public Window1()
    {
      InitializeComponent();

      Loaded += new RoutedEventHandler(ObjDialog_Loaded);
    }

    void ObjDialog_Loaded(object sender, RoutedEventArgs e)
    {
      XmlDocumentFragment frag = new XmlDocument().CreateDocumentFragment();
      frag.InnerXml = "<Style TargetType=\"{x:Type Window}\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"> " +
                      "  <Setter Property=\"Height\" Value=\"200\" />" +
                      "  <Setter Property=\"Width\" Value=\"200\" />" +
                      "</Style>";
      XmlNode node = frag.FirstChild as XmlElement;

      Style style = LoadXaml(node.OuterXml) as Style;
      if (style != null)
        Style = style;

      UpdateLayout();
    }

    private object LoadXaml(string xaml)
    {
      Exception ex = null;
      object o = LoadXaml(xaml, out ex);

      if (ex != null)
        throw ex;

      return o;
    }

    public static object LoadXaml(string xaml, out Exception exception)
    {
      try {
        ParserContext pc = new ParserContext();
        pc.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
        pc.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
        pc.XmlnsDictionary.Add("l", "http://www.teradp.com/schemas/GN4/1/WinUI");
        pc.XmlnsDictionary.Add("c", "clr-namespace:TeraDP.GN4.Common;assembly=Common");

        exception = null;
        return XamlReader.Load(new MemoryStream(Encoding.UTF8.GetBytes(xaml)), pc);
      }
      catch (Exception ex) {
        exception = ex;
      }

      return null;
    }

  }
}

When I run this code on Framework 3.5 the window is displayed with a size of 200x200.
When I run this code on Framework 4 thw window is displayed with a size of 500x400

The strangest thing is that if I add MinWidth and MinHeight to the style applied at runtime those attributes works correctly also in VS2010, while Width and Height seems to be ignored.

Do someone has a solution for this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

猫弦 2024-12-11 20:01:49

AFAIK 要更改窗口的显示方式和/或其大小,您应该实施 ArrangeOverride 或设置 高度 和 <直接 a href="http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.width.aspx" rel="nofollow noreferrer">Width (例如在 Loaded 事件句柄中)...

编辑 - 根据评论:

在运行时应用 XAML 可能会带来一些安全问题,因此我建议不要这样做或至少实施一些安全措施以防止动态加载的 XAML 干扰应用程序...也就是说:

此 MS Connect 条目 并非完全相同的问题,但在某种程度上相关,并且表明 WPF 4 中可能存在错误。

AFAIK to change how the window is shown and/or its size you should just implement ArrangeOverride OR set Height and Width directly (for example in the Loaded event handlet)...

EDIT - as per comment:

Applying XAML at runtime can open up several security problems so I would recommend not doing so or at least implement some security measures to prevent the dynamically loaded XAML from messing with the application... that said:

This MS Connect entry is not exactly the same issue but somehow related and suggests that there could be a bug in WPF 4.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文