1

我有一个 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;
        }
4

4 回答 4

2

是的,ActualWidth你需要寻找。但是 window 的构造函数不是获取它的正确位置,因为window is not rendered yet. 而是使用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;
}
于 2012-10-21T08:42:26.427 回答
1

假设您正在使用WPF 多文档界面

如果它是您需要对其进行宽度属性计算的 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);
        }
    }
于 2012-10-21T09:49:46.420 回答
1

正如我们一直在 WPF 房间里讨论这个问题一样,这是一个看似简单的复杂问题。

如果我们在 mdiChild 上设置宽度/高度,我们最终会失去调整大小的功能。所以我已经发布了一个修复的要点,根据我们的聊天似乎已经解决了这个问题


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

<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 handler source(你可以用这个替换现有的相关代码):

/// <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();
}
于 2012-10-26T14:31:37.020 回答
0

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

窥探

于 2012-10-21T09:52:38.757 回答