窗口的SizeToContent和ListBox的大小调整

3
我正在尝试使用WPF列表框和将SizeToContent属性设置为WidthAndHeight的窗口一起使用。MainWindow有一个带有两行两列的网格,在右下象限中,我有一个列表框。我希望窗口中其余的控件来控制窗口的大小,而列表框只需填充可用空间。目前,列表框正在扩展以适应其内容,这导致整个MainWindow扩展。
注意:我尝试创建了一个简单的示例,但是要指出,在我的真实情况下,我正在使用MVVM,并且要确定窗口宽度/高度的控件绑定到视图模型中的属性,在窗口加载后设置它们的值。
编辑添加:列表框在绑定到其内容之前,我无法控制要确定大小的控件。
以下是MainWindow启动时的当前外观:
请注意红色和蓝色条,这表明我不想发生的事情。该区域中的内容仅通过滚动条可见。
以下是我希望MainWindow在启动时的外观:
请注意,MainWindow的大小由顶部和左侧的文本块确定,列表框填充可用空间并在必要时使用滚动条。
以下是一些示例代码...
MainWindow.xaml:
<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" SizeToContent="WidthAndHeight">

<Grid>   
    <Grid.RowDefinitions>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="auto"/>
        <RowDefinition />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="auto"/>
        <ColumnDefinition />
    </Grid.ColumnDefinitions>

    <Grid Grid.Column="1">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="auto"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <TextBlock Text="The window should fit to the width of this" FontSize="15"/>

        <Canvas Background="Red" Grid.Column="1"/>
    </Grid>

    <Grid Grid.Row="1" Grid.RowSpan="2">
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <TextBlock Text="The window should fit to the height of this" FontSize="15">
            <TextBlock.LayoutTransform>
                <RotateTransform Angle="-90"/>
            </TextBlock.LayoutTransform>
        </TextBlock>

        <Canvas Background="Blue" Grid.Row="1"/>
    </Grid>

    <Grid Grid.Row="2" Grid.Column="1">
        <ListBox Name="ListBox1">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding}" />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Grid>

MainWindow.xaml.cs:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        var Messages = new ObservableCollection<string>() { "This is a long string to demonstrate that the list box content is determining window width" };

        for (int i = 0; i < 16; i++)
            Messages.Add("Test" + i);

        for (int i = 0; i < 4; i++)
            Messages.Add("this text should be visible by vertical scrollbars only");

        ListBox1.ItemsSource = Messages;
    }
}
1个回答

0

在窗口加载后,设置列表框的ItemsSource,并将SizeToContent设置为Manual。

public MainWindow()
{
    InitializeComponent();

    Loaded += OnLoaded;
}

private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
{
    SizeToContent = SizeToContent.Manual;

    var messages = new ObservableCollection<string>
        {
            "This is a long string to demonstrate that the list" + 
            " box content is determining window width"
        };

    for (int i = 0; i < 16; i++)
    {
        messages.Add("Test" + i);
    }

    for (int i = 0; i < 4; i++)
    {
        messages.Add("this text should be visible by vertical scrollbars only");
    }

    ListBox1.ItemsSource = messages;
}

这样,主窗口最初的大小适合内容(列表框中没有数据),然后列表框显示其项目并带有滚动条。


谢谢您的建议,它确实修复了我的示例。然而,我可能将我的示例简化得太多了,在我的真实场景中,我正在使用MVVM,并且我想要确定窗口宽度/高度的控件绑定到视图模型中的属性,在窗口加载后设置它们的值,因此我认为这不会起作用。 - The Dodge 3
@TheDodge3:将您的视图模型分成两个部分。最初,在您的示例中由列表框表示的数据将显示为空。然后,在视图模型上设置一个标志,在OnLoaded中设置该标志,使数据可用。 - Phil
据我理解,所提出的解决方案需要按照以下操作顺序进行:1)我想确定窗口宽度/高度的控件已经加载其内容(也许绑定是更好的词?),以便窗口大小适应它们。 2)设置SizeToContent=Manual,使窗口不再自动调整大小。 3)列表框内容被绑定。然而,在我的情况下,列表框在我想要确定大小的控件之前设置其内容,并且没有简单的方法可以更改。 - The Dodge 3
@TheDodge3。如果你愿意放弃纯MVVM,那么你可以在代码后台在适当的时候解除绑定并重新绑定listbox的ItemsSource。 - Phil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接