wpf 控制在打开窗口时随意移动

mklgxw1f  于 2023-10-22  发布在  其他
关注(0)|答案(3)|浏览(102)

我创建了一个wpf应用程序。应用程序的XAML代码如下。窗口运行时看起来很棒,但是当我尝试调整窗口大小时,控件会随意移动。我希望控制留在地方像一个适当的窗口应用程序。我也是WPF的新手。任何建议将不胜感激。
我已经插入了一个原来的图像和调整大小的窗口。

<Window x:Class="demoUI.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:demoUI"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="8*"/>
            <RowDefinition Height="17*"/>
            <RowDefinition Height="397*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="39*"/>
            <ColumnDefinition Width="113*"/>
            <ColumnDefinition Width="46*"/>
            <ColumnDefinition Width="12*"/>
            <ColumnDefinition Width="149*"/>
            <ColumnDefinition Width="38*"/>
            <ColumnDefinition Width="141*"/>
            <ColumnDefinition Width="256*"/>
        </Grid.ColumnDefinitions>
        <!--<Border BorderBrush="Black" BorderThickness="1" Grid.Column="6" Height="100" Margin="9.2,13,21.6,0" Grid.Row="1" Grid.RowSpan="2" VerticalAlignment="Top" HorizontalAlignment="Stretch"/>-->
        <Menu Margin="0,-4,56.2,5.8" Grid.ColumnSpan="2" Grid.RowSpan="2" >
            <MenuItem Header="File">
                <MenuItem Header="Open Log File"/>
                <MenuItem Header="Open Workspace"/>
                <Separator/>
                <MenuItem Header="Save as Workspace"/>
                <MenuItem Header="Set Path host file"/>
                <Border BorderBrush="Black" BorderThickness="1" Margin="-34,-117,-656.4,37.6"/>
            </MenuItem>
            <MenuItem Header="Control" Grid.Row="0" Grid.Column="1" Width="60">
                <MenuItem Header="Open Command Line View"/>
            </MenuItem>
        </Menu>
        <TextBlock Text="Connect To" Width="65" Height="Auto" HorizontalAlignment="Left" Margin="4,16.2,0,360.6" Grid.Row="2" Grid.ColumnSpan="2"/>
        <TextBox TextWrapping="Wrap" Text="IP/HostName" Margin="37.8,14.2,11.4,360.6" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Center" Grid.ColumnSpan="2"/>
        <TextBox TextWrapping="Wrap" Text="Line" Margin="100.8,46.2,12.4,328.6" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Center" Grid.ColumnSpan="2"/>

        <TextBlock Text="Protocol" Width="78" Height="Auto" HorizontalAlignment="Left" Margin="111.6,9,0,383.6" Grid.Column="4" Grid.ColumnSpan="3" Grid.RowSpan="2" Grid.Row="1"/>

        <StackPanel VerticalAlignment="Top" Grid.Column="3" Orientation="Horizontal" Grid.ColumnSpan="2" Height="48" Margin="2.6,0.2,0,0" Grid.Row="2" HorizontalAlignment="Left" Width="78">
            <Button Content="Play" HorizontalAlignment="Left" VerticalAlignment="Top" Height="20" Margin="4.5,14.2,0,0" Width="32"/>
            <Button Content="Stop" HorizontalAlignment="Right" VerticalAlignment="Top" Height="20" Margin="4.5,14.2,0,0" Width="32"/>
        </StackPanel>

        <StackPanel Orientation="Vertical" 
                    VerticalAlignment="Top" Grid.Column="4" Grid.ColumnSpan="2" Grid.Row="2"
                    HorizontalAlignment="Center" Width="34" Margin="123.6,6.2,28.8,0" Height="115">
            <TextBlock Text="Rx" Width="20" Height="Auto" HorizontalAlignment="Center"/>
            <CheckBox Margin="5,5,4.6,5" Height="14" />
            <CheckBox Margin="5,5,4.6,5" Height="14" RenderTransformOrigin="0.492,-0.286" />
            <CheckBox Margin="5,5,4.6,5" Height="14" />
            <CheckBox Margin="5,5,4.6,5" Height="14" />
        </StackPanel>
        <StackPanel Orientation="Vertical" 
                    VerticalAlignment="Top" Grid.Column="5" Grid.ColumnSpan="2" Grid.Row="2"
                    HorizontalAlignment="Left" Margin="4.8,6.2,0,0" Height="124" Width="36">
            <TextBlock Text="Tx" Width="20" Height="Auto" HorizontalAlignment="Center" />
            <CheckBox Margin="5,5,4.8,5" Height="14" />
            <CheckBox Margin="5,5,4.8,5" Height="14" />
            <CheckBox Margin="5,5,4.8,5" Height="14" />
            <CheckBox Margin="5,5,4.8,5" Height="14" />
        </StackPanel>

        <TextBlock Text="Log Cmd" Width="65" Height="Auto" HorizontalAlignment="Left" Margin="9,51.2,0,325.6" Grid.Row="2" Grid.ColumnSpan="2"/>
        <TextBlock TextWrapping="Wrap" Text="RSP" Margin="93.6,25.2,15.2,348.6"  Grid.Column="4" Grid.Row="2" />
        <TextBlock TextWrapping="Wrap" Text="RTU" Margin="93.6,49.2,15.2,327.6" Grid.Column="4" Grid.Row="2" />
        <TextBlock TextWrapping="Wrap" Text="Error" Margin="93.6,69.2,15.2,307.6" Grid.Column="4" Grid.Row="2"/>
        <TextBlock TextWrapping="Wrap" Text="Info" Margin="93.6,96.2,15.2,280.6" Grid.Column="4" Grid.Row="2" />

        <ComboBox x:Name="Job"
                  VerticalAlignment="Bottom" Margin="38.8,0,16,324.6"
                  Height="23" Grid.Row="2" Grid.Column="1">
            <ComboBoxItem Content="Trace"/>
            <ComboBoxItem Content="List"/>
            <ComboBoxItem Content="Dump"/>
            <ComboBoxItem Content="Off"/>
        </ComboBox>
        <StackPanel Grid.Column="3" Grid.Row="2" Grid.ColumnSpan="2" Margin="3.6,52.2,82.2,315.6">
            <Button Content="Send" VerticalAlignment="Top" Height="20" Margin="3,0,0,0" HorizontalAlignment="Left" Width="69"/>
        </StackPanel>
    </Grid>
</Window>

t3irkdon

t3irkdon1#

导致TextBoxesComboBox漂移的直接原因是它们的VerticalAlignment被设置为Center,并且它们被使用巨大的底部边缘偏移回行的顶部。
它们也在Grid的第三行中,所有行的Height都以一种使它们缩放到父容器(窗口)大小的方式设置。Height="8*"Height="17*"等中的星星“*”。导致行以指定的比例填充其父级中的剩余空间。
这一切背后的罪魁祸首很可能是使用设计器将所有内容拖放到其位置,而不是注意使用WPF中可用的各种面板/容器。
至少,您应该通过自己编写代码来创建初始面板设置。这将导致更干净和更多的维护代码。我建议在开始使用WPF时,只将设计器用作反馈工具。
这可能是您正在寻找的布局:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Menu Grid.Row="0">
        <MenuItem Header="File">
            <MenuItem Header="Open Log File" />
            <MenuItem Header="Open Workspace" />
            <Separator />
            <MenuItem Header="Save as Workspace" />
            <MenuItem Header="Set Path host file" />
        </MenuItem>
        <MenuItem Header="Control">
            <MenuItem Header="Open Command Line View" />
        </MenuItem>
    </Menu>
    <WrapPanel Grid.Row="1" Margin="10">
        <WrapPanel.Resources>
            <Style TargetType="Grid">
                <Setter Property="Margin" Value="0,0,20,0" />
            </Style>
        </WrapPanel.Resources>
        <Grid>
            <Grid.Resources>
                <Style TargetType="TextBox">
                    <Setter Property="Margin" Value="3" />
                    <Setter Property="VerticalContentAlignment" Value="Center" />
                </Style>
                <Style TargetType="TextBlock">
                    <Setter Property="Margin" Value="3" />
                    <Setter Property="VerticalAlignment" Value="Center" />
                </Style>
                <Style TargetType="ComboBox">
                    <Setter Property="Margin" Value="3" />
                    <Setter Property="VerticalContentAlignment" Value="Center" />
                </Style>
            </Grid.Resources>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <TextBlock VerticalAlignment="Center" Text="Connect To" />
            <TextBox
                Grid.Column="1"
                Grid.ColumnSpan="2"
                Text="IP/HostName" />
            <TextBlock Grid.Row="1" Text="Log Cmd" />
            <ComboBox
                x:Name="Job"
                Grid.Row="1"
                Grid.Column="1">
                <ComboBoxItem Content="Trace" />
                <ComboBoxItem Content="List" />
                <ComboBoxItem Content="Dump" />
                <ComboBoxItem Content="Off" />
            </ComboBox>
            <TextBox
                Grid.Row="1"
                Grid.Column="2"
                VerticalContentAlignment="Center"
                Text="Line" />
        </Grid>
        <Grid>
            <Grid.Resources>
                <Style TargetType="Button">
                    <Setter Property="Margin" Value="3" />
                </Style>
            </Grid.Resources>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Button Content="  Play  " />
            <Button Grid.Column="1" Content="  Stop  " />
            <Button
                Grid.Row="1"
                Grid.ColumnSpan="2"
                Content="  Job  " />
        </Grid>
        <Grid>
            <Grid.Resources>
                <Style TargetType="TextBlock">
                    <Setter Property="Margin" Value="3" />
                </Style>
                <Style TargetType="CheckBox">
                    <Setter Property="Margin" Value="3" />
                </Style>
            </Grid.Resources>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <TextBlock Grid.ColumnSpan="3" Text="Protocol" />
            <TextBlock
                Grid.Row="1"
                Grid.Column="1"
                Text="Rx" />
            <TextBlock
                Grid.Row="1"
                Grid.Column="2"
                Text="Tx" />
            <TextBlock Grid.Row="2" Text="RSP" />
            <CheckBox Grid.Row="2" Grid.Column="1" />
            <CheckBox Grid.Row="2" Grid.Column="2" />

        </Grid>
    </WrapPanel>
</Grid>

另外,我建议阅读以下关于WPF https://www.codeproject.com/Articles/140613/WPF-Tutorial-Layout-Panels-Containers-Layout-Trans中的面板和容器的文章
编辑:除此之外,我建议避免为容器和大多数控件设置硬WidthHeight。也不要害怕将容器嵌套到另一个容器中以实现所需的结果。创建和使用嵌套容器比使用mega Grid要容易得多。

e5nszbig

e5nszbig2#

主要问题在于行/列定义。通过使用带星号的值,您可以指示应用程序相对于其他列/行缩放宽度/高度。
换句话说,要使控件在关闭时保持不变,请从ColumnDefinitions/RowDefinitions中删除星号。

jogvjijk

jogvjijk3#

我的c# wpf应用程序遇到了这个问题。当我调整窗口大小时,所有的文本框和按钮都保持不变,但图像一直在移动。我的xaml代码看起来类似于这样:

<Grid>
    <TextBlock Margin="58,10,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" TextWrapping="Wrap" Text="Hello World"  Width="271" Height="28" FontSize="18"/>
    <Image Margin="5,5,735.6,372" Source="image.png" Stretch="None"/>
</Grid>

我是如何修复它的:当我点击图像并查看Visual Studio中VerticalAlignmentHorizontalAlignment的属性时,它们在属性中都设置为“Stretch”,尽管它不在xaml代码中。所以我把它们都设置为“上”和“左”。这使图像无法移动。
然而,如果我从底部缩小窗口,那么一个背景色的框将开始覆盖图像,如果我从右侧缩小窗口,那么背景色的框将开始覆盖图像。为了解决这个问题,我必须将图像的第三和第四个参数Margin设置为0。因此,图像边距现在是“5,5,0,0”。
下面是最终的工作xaml代码:

<Grid>
    <TextBlock Margin="58,10,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" TextWrapping="Wrap" Text="Hello World"  Width="271" Height="28" FontSize="18"/>
    <Image Margin="5,5,0,0" Source="image.png" VerticalAlignment="Top" HorizontalAlignment="Left" Stretch="None"/>
</Grid>

我不知道为什么Visual Studio插入了所有的文本框和按钮,并正确对齐和边距,但它没有这样做的图像。

相关问题