.net 如何避免窗口小于 WPF 中 UserControl 的最小大小?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9319248/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 16:15:06  来源:igfitidea点击:

How to avoid having a Window smaller than the minimum size of a UserControl in WPF?

.netwpfsizeresize

提问by Ignacio Soler Garcia

I have an usercontrol (a statusbar) that has an implicit minimum size (not set via the property, what I mean is that when it reaches a minimum size it can not be reduced and it's cropped).

我有一个用户控件(一个状态栏),它有一个隐式的最小尺寸(不是通过属性设置的,我的意思是当它达到最小尺寸时,它不能减小并且被裁剪)。

Is there a way to let the main window know that the UserControl will being to be cropped and don't allow it to reduce its size? With such a smart layout system as WPF has it must be a way that it knows that it's cropping things. Look at the next image:

有没有办法让主窗口知道 UserControl 将被裁剪并且不允许它减小其大小?有了像 WPF 这样的智能布局系统,它必须是一种知道它正在裁剪东西的方式。看下一张图:

enter image description here

在此处输入图片说明

回答by Arijit Mukherjee

Include MinHeight="MinSize" MinWidth="MinSize"inside the <Window>section

包含MinHeight="MinSize" MinWidth="MinSize"<Window>部分内

MinSize = Desired Integer Value ex 400/350 etc.

MinSize = 期望的整数值,例如 400/350 等。

<Window x:Class="IOTA_WPF.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" 
    WindowState="Maximized"
    MinHeight="400" MinWidth="650">

回答by denver

I know this is several years after the fact, but I recently ran across this question as I was dealing with a similar problem I had. This is how I solved it. The solution is specific to my problem, but can be altered to get a variety of desired resizing behaviors.

我知道这是事后几年,但我最近遇到了这个问题,因为我正在处理我遇到的类似问题。我就是这样解决的。该解决方案特定于我的问题,但可以更改以获得各种所需的调整大小行为。

First set the window so that it initially sizes itself to fit its contents.

首先设置窗口,使其初始大小适合其内容。

<Window ...
    SizeToContent="WidthAndHeight" >

Next I set each embedded control so that it reports a desired width and height. Most built in controls do this for you. You can do it for custom controls by overriding MeasureOverride or you can just set a width and height for the control. Make this the minimum size you want the control to get.

接下来我设置每个嵌入式控件,以便它报告所需的宽度和高度。大多数内置控件都会为您执行此操作。您可以通过覆盖 MeasureOverride 来为自定义控件执行此操作,或者您可以只为控件设置宽度和高度。使其成为您希望控件获得的最小尺寸。

<MyControl Name="_MyControlName" Width="640" Height="480" />

Don't worry about these 'hard' coded values effecting the behavior of the control. We deal with that next. Now when the window is displayed it will automatically adjust itself to fit your controls.

不要担心这些“硬”编码值会影响控件的行为。我们接下来处理。现在,当窗口显示时,它会自动调整以适应您的控件。

Next subscribe to the window loaded event.

接下来订阅窗口加载事件。

<Window ...
    SizeToContent="WidthAndHeight" Loaded="Window_Loaded" >

In the window loaded event you can adjust the sizing behavior of your window and the controls in it. You can make it so your controls can resize. You can set a minimum size for the window to the size you just had layed out. The advantage here is that you just allowed the layout system to find a good layout for you. You want to leverage its work.

在窗口加载事件中,您可以调整窗口及其中控件的大小调整行为。您可以设置它以便您的控件可以调整大小。您可以将窗口的最小尺寸设置为您刚刚布置的尺寸。这里的优点是您只是允许布局系统为您找到一个好的布局。你想利用它的工作。

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        // We know longer need to size to the contents.
        ClearValue(SizeToContentProperty);
        // We want our control to shrink/expand with the window.
        _MyControlName.ClearValue(WidthProperty);
        _MyControlName.ClearValue(HeightProperty);
        // Don't want our window to be able to get any smaller than this.
        SetValue(MinWidthProperty, this.Width);
        SetValue(MinHeightProperty, this.Height);
    }

What you place in the Window_Loaded method will depend on the behavior you are trying to accomplish.

您在 Window_Loaded 方法中放置的内容将取决于您尝试完成的行为。

Hope this can help some others save time.

希望这可以帮助其他一些人节省时间。

回答by MasterOfDesaster

I know that I'm a little late but I would tell that I've found nearly the cleanest solution for this issue.

我知道我有点晚了,但我会说我已经找到了解决这个问题的最干净的解决方案。

1.) Create a custom UserControl (if you are using any)

1.) 创建一个自定义 UserControl(如果您正在使用)

public class ExtendedUserControl : UserControl
{
    public static readonly RoutedEvent ContentChangedEvent
    = EventManager.RegisterRoutedEvent(
        "ContentChanged",
        RoutingStrategy.Bubble,
        typeof(RoutedEventHandler),
        typeof(ExtendedUserControl));

    public event RoutedEventHandler ContentChanged
    {
        add { AddHandler(ContentChangedEvent, value); }
        remove { RemoveHandler(ContentChangedEvent, value); }
    }

    protected override void OnContentChanged(object oldContent, object newContent)
    {
        base.OnContentChanged(oldContent, newContent);
        RaiseEvent(new RoutedEventArgs(ContentChangedEvent, this));
    }
}

2.) Attach the event to your UserControl

2.) 将事件附加到您的 UserControl

<extended:ExtendedUserControl Height="auto" Width="auto" cal:View.Model="{Binding CurrentModel}" ContentChanged="ExtendedUserControl_ContentChanged"/>

3.) UPDATEDNow we come to the last part of the solution.

3.)更新现在我们来到解决方案的最后一部分。

private void ExtendedUserControl_ContentChanged(object sender, System.Windows.RoutedEventArgs e)
    {
        Thread task = new Thread(() =>
        {
            Dispatcher.Invoke(() =>
            {
                SizeToContent = SizeToContent.WidthAndHeight;
                MinHeight = Height;
                MinWidth = Width;
            });
        });
        task.Start();
    }

Cheers

干杯

回答by Phil Wright

You can set the controls MinHeight property to prevent it getting smaller that desired.

您可以设置控件 MinHeight 属性以防止它变得比所需的更小。

回答by CodeWarrior

Can you put items in a Grid with Rows containing the constituent parts?

您可以将项目放入包含组成部分的行的网格中吗?

All items that must have a minimum height can go in rows with a similar minimum height.

所有必须具有最小高度的项目都可以排列在具有相似最小高度的行中。

Add the minimum heights up = Window.MinHeight. Thus the window can never be smaller than the collective minimum heights of the necessary rows, so those rows should always display.

将最小高度加起来 = Window.MinHeight。因此,窗口永远不会小于必要行的集体最小高度,因此这些行应始终显示。

回答by Rick Hodder

I think I remember reading somewhere (I may be wrong) that stack panels have borders based on infinity, and cannot handle such sizing issues.

我想我记得在某处(我可能是错的)读到堆栈面板具有基于无穷大的边框,并且无法处理此类尺寸问题。

From http://msdn.microsoft.com/en-us/library/ms754152.aspx

来自http://msdn.microsoft.com/en-us/library/ms754152.aspx

DockPanel vs StackPanel

DockPanel 与 StackPanel

Although DockPanel can also "stack" child elements, DockPanel and StackPanel do not produce analogous results in some usage scenarios. For example, the order of child elements can affect their size in a DockPanel but not in a StackPanel. This is because StackPanel measures in the direction of stacking at PositiveInfinity, whereas DockPanel measures only the available size.

虽然 DockPanel 也可以“堆叠”子元素,但 DockPanel 和 StackPanel 在某些使用场景下不会产生类似的结果。例如,子元素的顺序会影响它们在 DockPanel 中的大小,但不会影响 StackPanel 中的大小。这是因为StackPanel 在 PositiveInfinity 的堆叠方向上进行测量,而 DockPanel 仅测量可用大小。

There's a section of the post where it talks about nested panels too. Which might be what you need.

帖子的一部分也谈到了嵌套面板。这可能是您需要的。

Or maybe use a grid with the status in the bottom row?

或者也许使用带有底行状态的网格?