gpt4 book ai didi

带有自定义镶边的 WPF 窗口在右侧和底部有不需要的轮廓

转载 作者:行者123 更新时间:2023-12-04 04:04:56 26 4
gpt4 key购买 nike

我使用 Microsoft.Windows.Shell dll 创建了一个带有自定义镶边的 WPF 窗口。
这是代码:

<Style TargetType="Window" x:Key="ChromeLessWindowStyle">
<Setter Property="shell:WindowChrome.WindowChrome">
<Setter.Value>
<shell:WindowChrome
GlassFrameThickness="0"
ResizeBorderThickness="5"
CornerRadius="5"
CaptionHeight="30">
</shell:WindowChrome>
</Setter.Value>
</Setter>
<Setter Property="WindowStyle" Value="None"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Grid>
<Grid Background="#FF595959" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" Height="30" Background="#FF393939">
<DockPanel LastChildFill="False" Margin="0,1,5,0">
<TextBlock DockPanel.Dock="Left" Style="{DynamicResource {x:Static coreKeys:TextBlockKeys.Default}}" FontWeight="Bold" Text="{TemplateBinding Title}" Margin="10,0,0,0" VerticalAlignment="Center"/>
<!--Buttons-->
<Button DockPanel.Dock="Right" behaviors:WindowCommandBehaviors.IsCloseButton="True" Style="{DynamicResource {x:Static coreKeys:ButtonKeys.Close}}" shell:WindowChrome.IsHitTestVisibleInChrome="True"/>
<Button DockPanel.Dock="Right" behaviors:WindowCommandBehaviors.IsMaximizeButton="True" Style="{DynamicResource {x:Static coreKeys:ButtonKeys.Maximize}}" Visibility="{TemplateBinding WindowState,Converter={StaticResource WindowStateToVisibilityConverter},ConverterParameter=MaximizeButton }" shell:WindowChrome.IsHitTestVisibleInChrome="True" />
<Button DockPanel.Dock="Right" behaviors:WindowCommandBehaviors.IsMaximizeButton="True" Style="{DynamicResource {x:Static coreKeys:ButtonKeys.Restore}}" Visibility="{TemplateBinding WindowState,Converter={StaticResource WindowStateToVisibilityConverter}, ConverterParameter=RestoreButton }" shell:WindowChrome.IsHitTestVisibleInChrome="True" />
<Button DockPanel.Dock="Right" behaviors:WindowCommandBehaviors.IsMinimizeButton="True" Style="{DynamicResource {x:Static coreKeys:ButtonKeys.Minimize}}" shell:WindowChrome.IsHitTestVisibleInChrome="True"/>
</DockPanel>
</Border>
<ContentPresenter Grid.Row="1" Content="{TemplateBinding Content}"/>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

这在正常情况下非常有效,直到我需要使用 C# 代码使用窗口时才发现问题。
我有一个消息服务:
  • 创建一个模态窗口。
  • 使用 WPF 用户控件填充其内容。
  • 将窗口的数据上下文设置为适当的 ViewModel。
  • 显示窗口

  • 这是代码:
    var userControl = viewRegistry.GetViewByKey(viewKey_); // Get the UserControl.
    var modalWindow = new ModalCustomMessageDialog
    {
    // Set the content of the window as the user control
    DataContext = viewModel_,
    // Set the data context of the window as the ViewModel
    Owner = Util.AppMainWindow,
    // Set the owner of the modal window to the app window.
    WindowStartupLocation = WindowStartupLocation.CenterOwner,
    //Title = viewModel.TitleText ?? "",
    ShowInTaskbar = false,
    Content = userControl,
    SizeToContent = SizeToContent.WidthAndHeight
    };
    if (showAsToolWindow_)
    {
    modalWindow.ResizeMode = ResizeMode.NoResize;
    modalWindow.WindowStyle = WindowStyle.ToolWindow;
    }
    modalWindow.Loaded += modalWindow_Loaded;
    modalWindow.Closed += CleanModalWindow;
    modalWindow.Show();

    注意线
    SizeToContent = SizeToContent.WidthAndHeight

    这负责调整窗口大小以符合用户控件的宽度和高度。
    这样生成的模态窗口在窗口的右侧和底部有一个粗黑的轮廓。像这样:

    Window with the outline

    窗口应该是这样的(并且在调整大小之后):

    Good window

    有几点值得注意:
  • 一旦调整窗口大小,这个黑色轮廓就会消失。
  • 如果 SizeToContent 设置为 SizeToContent.Height 或 SizeToContent.Width,则不会出现此大纲。但随后它会分别吹掉模态窗口的宽度或高度。
  • 我认为重绘窗口可能存在一些问题。所以我尝试了以下代码来重绘窗口:
    private const int WmPaint = 0x000F;

    [DllImport("User32.dll")]
    public static extern Int64 SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
    ......................
    //Inside the Loaded event handler of the modalWindow
    var windowHandle = new WindowInteropHelper(modalWindow).Handle;
    SendMessage(windowHandle, WmPaint, IntPtr.Zero, IntPtr.Zero);

    这没有效果。
  • 如果我为填充窗口的用户控件提供了固定的高度和宽度属性,则不会出现此问题。但是,我不能总是这样做。
  • 消息服务已经存在很长时间了,这个幽灵轮廓最近在自定义 chrome 更改后出现了。

  • 有没有人遇到过类似的情况?任何帮助将不胜感激。

    最佳答案

    我最近在包含动态生成的元素的窗口上使用自定义窗口镶边时遇到了这个问题。

    为什么会这样?

    如果我们使用具有静态内容的窗口,则窗口可以在初始化时知道​​包含其子元素所需的最大宽度/高度。

    如果我们想使用具有自动缩放功能的动态元素,例如使用 MVVM 模式的 View ,我们需要在其所有绑定(bind)(例如 View )已解决后请求窗口更新其视觉状态。

    解决方案

    为了强制执行我们上面推理的行为,我们需要使用窗口的 ContentRendered 事件,并将其用于 InvalidateVisual()。

    在您遇到问题的窗口的 XAML 中:

    ContentRendered="Window_OnContentRendered"

    在代码隐藏中:
    private void Window_OnContentRendered(object sender, EventArgs e)
    {
    InvalidateVisual();
    }

    祝你好运。

    关于带有自定义镶边的 WPF 窗口在右侧和底部有不需要的轮廓,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29207331/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com