在Loaded中设置WPF对话框的大小会导致闪烁并先显示默认大小

问题描述 投票:0回答:1

由于某些原因,我无法直接在 xaml 中使用

SizeToContent="WidthAndHeight"

我尝试使用
Loaded
事件。但似乎当调用我的尺寸设置函数时,对话框已经显示了。因此,我将首先看到一个(可能)默认大小的对话框,然后在
SetDialogWidthBasedOnContent
完成后,对话框再次以另一个大小刷新。我做了一些搜索,发现
Loaded
已经处于可以测量正确尺寸的最早阶段。那么避免第一个对话框尺寸错误的正确方法是什么?
我还尝试直接在
ShowDialog();
之前设置大小,但这会导致大小错误,可能是因为该大小是在渲染对话框之前设置的。

这是我的代码示例:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        Loaded += SetDialogWidthBasedOnContent;
    }

    void SetDialogWidthBasedOnContent(object sender, EventArgs e)
    {
        double maxWidth = 0;

        foreach (UIElement child in RootStackPanel.Children)
        {
            // Measure each child
            child.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));

            // Get the desired width of the current child
            double childWidth = child.DesiredSize.Width;

            // If the child has margins, add them too
            if (child is FrameworkElement fe)
            {
                childWidth += fe.Margin.Left + fe.Margin.Right;
                if (fe is Control control)
                {
                    childWidth += control.Padding.Left + control.Padding.Right;
                }
            }

            // Keep track of the maximum width found
            if (childWidth > maxWidth)
            {
                maxWidth = childWidth;
            }
        }

        // Get StackPanel's own margins
        double parentMarginLeft = RootStackPanel.Margin.Left;
        double parentMarginRight = RootStackPanel.Margin.Right;
        maxWidth += parentMarginLeft + parentMarginRight;

        // Set the dialog width to the calculated width
        Width = maxWidth;
    }
}

这是 xaml 示例:

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow">
    <Grid x:Name="RootStackPanel" VerticalAlignment="Center" Margin="20,20,20,20">
        <CheckBox Margin="0,10,0,0">
            <TextBlock Text="this is a test text." />
        </CheckBox>
    </Grid>
</Window>
c# wpf
1个回答
0
投票

所以我不知道为什么要这样做。但我认为你是对的。但是您是否尝试过通过“ContentRendered”事件来解决它?使用 ContentRendered 事件可确保在内容完全呈现后进行大小调整。这应该可以减少闪烁,但如果仍然发生,您可能需要探索其他选项。

这可能是一个廉价的机会,但据我所知,这将是最快的方法。

您还可以尝试将初始窗口设置为隐藏,执行您的操作,然后加载它。这将解决调整大小的问题。

这两种方法都很肮脏,但可能有效

    {
        InitializeComponent();
        Loaded += OnLoaded;
    }

    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        this.Visibility = Visibility.Hidden;
        SetDialogWidthBasedOnContent();
        this.Visibility = Visibility.Visible;
    }
   
© www.soinside.com 2019 - 2024. All rights reserved.