【问题标题】:Unable to get window width无法获取窗口宽度
【发布时间】:2012-10-21 08:34:02
【问题描述】:

我有一个 WPF 窗口,我正在尝试获取 Width 属性。无论我尝试在哪里显示代码,它总是返回为NaN。我在互联网上查找并读到我实际上应该使用ActualWidth,但无论如何这都会返回 0。

如何摆脱滞后并获得窗口宽度的实际值?

XAML:

<Window x:Name="TableWindow" x:Class="QueryBuilder.DatabaseTable"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        WindowStyle="None" Background="Transparent" SizeToContent="WidthAndHeight" ResizeMode="CanResize">
    <Grid>
        <DockPanel>
            <StackPanel Name="titleBar" DockPanel.Dock="Top" Height="28" FlowDirection="RightToLeft" Orientation="Horizontal" Background="AliceBlue">
                <Button x:Name="btnClose" Margin="0,0,5,0" Click="btnClose_Click">
                </Button>
                <Button>
                </Button>
                <Button>
                </Button>
                <Button x:Name="btnAll">ALL</Button>
                <Label Name="lblTableName" FontSize="15" Margin="50,0,0,0"></Label>
            </StackPanel>
            <StackPanel Orientation="Vertical" Name="spFields">
            </StackPanel>
        </DockPanel>
    </Grid>
</Window>

XAML.cs:

public DatabaseTableWindow(string tableName, DataTable fields, string primaryKey)
        {
            InitializeComponent();
            this.tableName = tableName;
            this.fields = fields;
            this.primaryKey = primaryKey;
            lblTableName.Content = tableName;
            double x = this.ActualWidth;
        }

【问题讨论】:

    标签: c# .net wpf xaml window


    【解决方案1】:

    是的,ActualWidth 你需要寻找。但是自从window is not rendered yet 以来,window 的构造函数并不是获取它的正确位置。而是使用Loaded 事件-

    public DatabaseTableWindow(string tableName, DataTable fields, string primaryKey)
    {
        InitializeComponent();
        this.tableName = tableName;
        this.fields = fields;
        this.primaryKey = primaryKey;
        lblTableName.Content = tableName;
        Loaded += new RoutedEventHandler(MainWindow_Loaded);        
    }
    
    void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        double x = this.ActualWidth;
    }
    

    编辑

    代替Loaded,尝试在构造函数中挂钩ContentRendered 事件-

    this.ContentRendered += new EventHandler(MainWindow_ContentRendered);
    
    void MainWindow_ContentRendered(object sender, EventArgs e)
    {
       double x = this.ActualWidth;
    }
    

    【讨论】:

    • 我试过这样做,但由于某种原因没有调用该事件。我已经完全复制了你的代码。可能是因为我使用的是 WPF MDI 插件,而窗口包含在 MdiChild 中?
    • 我猜这与库有关,因为窗口包含在 MdiChild 中
    • AFAIK 您将 tableWindow 的内容复制到 MDIChild 的内容。因此,窗口的加载事件永远不会被触发。查找可用于获取宽度的任何事件,构造函数不是正确的位置。
    • 我尝试了 MdiChild 加载事件,该事件成功触发。但是我无法从那里获得 TableWindow 的宽度,因为它继续返回 0
    • 检查 MDIChild 本身的ActualWidth,因为它与 TableWindow 的宽度相同,因为内容完全相同。不是吗?
    【解决方案2】:

    我们一直在 WPF 会议室讨论这个问题,这是一个看似简单的复杂问题。

    如果我们在 mdiChild 上设置宽度/高度,我们最终会失去调整大小的功能。所以我根据我们的chat

    发布了一个似乎已经解决了这个问题的修复要点

    所以为了获得大小限制,我使用了普通绑定(这个复制粘贴来自我的测试项目):

    <Window x:Class="TestApplication.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:MDI="clr-namespace:WPF.MDI;assembly=WPF.MDI" xmlns:TestApplication="clr-namespace:TestApplication"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Title="MainWindow">
        <MDI:MdiContainer Name="mainContainer">
            <MDI:MdiChild x:Name="mdiChild" MaximizeBox="False" MinimizeBox="False" Resizable="True" ShowIcon="False" Width="{Binding Width, ElementName=childElement}" Height="{Binding Height, ElementName=childElement}">
                <TestApplication:DatabaseTable x:Name="childElement"/>
            </MDI:MdiChild>
        </MDI:MdiContainer>
    </Window>
    

    这解决了主要的宽度和高度问题。


    这段代码需要替换 WPF.MDI 库中的MdiChild.cs Changeset 81799 resize 处理程序源(你可以用这个替换现有的相关代码):

    /// <summary>
    /// Handles the DragDelta event of the ResizeLeft control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.Windows.Controls.Primitives.DragDeltaEventArgs"/> instance containing the event data.</param>
    private void ResizeLeft_DragDelta(object sender, DragDeltaEventArgs e)
    {
        if (ActualWidth - e.HorizontalChange < MinWidth)
            return;
    
        double newLeft = e.HorizontalChange;
    
        if (Position.X + newLeft < 0)
            newLeft = 0 - Position.X;
    
        Width = ActualWidth - newLeft;
        Position = new Point(Position.X + newLeft, Position.Y);
    
        if (sender != null)
            Container.InvalidateSize();
    }
    
    /// <summary>
    /// Handles the DragDelta event of the ResizeTop control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.Windows.Controls.Primitives.DragDeltaEventArgs"/> instance containing the event data.</param>
    private void ResizeTop_DragDelta(object sender, DragDeltaEventArgs e)
    {
        if (ActualHeight - e.VerticalChange < MinHeight)
            return;
    
        double newTop = e.VerticalChange;
    
        if (Position.Y + newTop < 0)
            newTop = 0 - Position.Y;
    
        Height = ActualHeight - newTop;
        Position = new Point(Position.X, Position.Y + newTop);
    
        if (sender != null)
            Container.InvalidateSize();
    }
    
    /// <summary>
    /// Handles the DragDelta event of the ResizeRight control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.Windows.Controls.Primitives.DragDeltaEventArgs"/> instance containing the event data.</param>
    private void ResizeRight_DragDelta(object sender, DragDeltaEventArgs e)
    {
        if (ActualWidth + e.HorizontalChange < MinWidth)
            return;
    
        Width = ActualWidth + e.HorizontalChange;
    
        if (sender != null)
            Container.InvalidateSize();
    }
    
    /// <summary>
    /// Handles the DragDelta event of the ResizeBottom control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.Windows.Controls.Primitives.DragDeltaEventArgs"/> instance containing the event data.</param>
    private void ResizeBottom_DragDelta(object sender, DragDeltaEventArgs e)
    {
        if (ActualHeight + e.VerticalChange < MinHeight)
            return;
    
        Height = ActualHeight + e.VerticalChange;
    
        if (sender != null)
            Container.InvalidateSize();
    }
    

    【讨论】:

    • 非常感谢您的帮助:)
    【解决方案3】:

    假设您正在使用WPF Multiple Document Interface

    如果它是 MdiChild,您需要对其进行宽度属性计算,那么您可以在将其添加到容器之前绑定到 MdiChild 对象的 Loaded-Event。

            var mdiChild = new MdiChild
                               {
                                   Title = "Window Using Code",
                                   Content = new ExampleControl(),
                                   Width = 714,
                                   Height = 734,
                                   Position = new Point(200, 30)
                               };
        mdiChild.Loaded += new RoutedEventHandler(mdiChild_Loaded);
    
            Container.Children.Add(mdiChild);
    

        void mdiChild_Loaded(object sender, RoutedEventArgs e)
        {
            if (sender is MdiChild)
            {
                var width = (sender as MdiChild).Width;
                Debug.WriteLine("Width: {0}", width);
            }
        }
    

    【讨论】:

    • 正如我在下面的另一个答案中讨论的那样,这是不可能的,因为加载的事件永远不会被调用。窗口包含在 MdiChild 对象中
    • 你能给我发一个示例项目吗?
    • 请看一下新的答案。希望这会有所帮助。我不知道您使用的是哪个“MDI 库”。
    • 那么现在标记为1的答案实际上也不对。
    • 问题是我要求 MdiChild 对象与内容部分中指定的窗口大小相同。为此,我需要获得我似乎无法管理的内容控件的宽度。我使用的插件实际上是您链接的插件。
    【解决方案4】:

    尝试窥探窗口并越过树查看值

    snoop

    【讨论】:

      猜你喜欢
      • 2016-06-02
      • 1970-01-01
      • 2013-10-10
      • 2018-08-12
      • 2012-01-21
      • 2018-10-23
      • 2020-02-27
      • 2019-10-03
      • 2014-05-20
      相关资源
      最近更新 更多