WPF弹出窗口在内容更改时未调整大小

问题描述 投票:0回答:1

尽管正在寻找类似的情况,但我找不到与自动调整弹出内容大小有关的任何内容。

最终,我错过了一些显而易见的事情,但是当内容创建后,我的弹出窗口坚决拒绝在内容更改时重新计算其大小和内容布局。

更确切地说:我的弹出窗口托管一个ListView,其内容会动态更改。

现在,当第一次创建弹出窗口时,其宽度将适应所需的ListView大小,以便所有列表视图元素(在GridView内部)。

Initial Popup created properly

现在更新ListView中的元素时,最长元素的宽度发生变化。预期的行为是列表视图和弹出窗口将更改大小(宽度)以匹配新的列表元素。

不幸的是,弹出窗口及其内容只是拒绝更改,因此,内容被裁剪了。

Height does change, but width just refuses to update

我已经尝试使弹出窗口的布局和尺寸无效,并调用了Popup和/或ListView的UpdateLayout,到目前为止没有成功...我无法访问/管理的GridView元素...

是否有办法强制重新计算Popup或ListView的总布局?

<Popup x:Name           = "hintPopup"
       Placement        = "Bottom"
       PlacementTarget  = "{Binding ElementName=textBox}"
       MinWidth         = "{Binding ElementName=textBox, Path=ActualWidth}"
       IsOpen           = "{Binding ShowPopup, RelativeSource={RelativeSource AncestorType=ccont:vokDataGridEdit}}"
       Margin           = "0,20,0,0">

    <!-- Reference a converter to convert Bool Values to Visibility -->
    <Popup.Resources>
        <conv:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
    </Popup.Resources>

    <!-- Move popup with anchor -->
    <b:Interaction.Behaviors>
        <behav:PopupAutoRepositionBehavior />
    </b:Interaction.Behaviors>

    <Border BorderBrush     = "Gray" 
            BorderThickness = "1"
            Background      = "LightGray"
            Padding         = "1">

        <StackPanel Orientation="Vertical">

            <!-- Title Starts With -->
            <TextBlock Text         = "{x:Static res:Strings.vokDataGridEdit_Popup_TitleStartsWith}"
                       Visibility   = "{Binding ShowHintsStartsWith, RelativeSource={RelativeSource AncestorType=ccont:vokDataGridEdit}, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=collapsed}"
                       FontWeight   = "Bold"
                       Foreground   = "Black"
                       Margin       = "0, 5, 0, 2"/>

            <!-- Hints -->
            <ListView ItemsSource   = "{Binding ItemHintsStartsWith, Mode=TwoWay, RelativeSource={RelativeSource AncestorType=ccont:vokDataGridEdit}}"
                      Visibility    = "{Binding ShowHintsStartsWith, RelativeSource={RelativeSource AncestorType=ccont:vokDataGridEdit}, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=collapsed}"
                      Margin        = "5, 1, 1, 1">

                <!-- Prevent selection -->
                <ListView.ItemContainerStyle>
                    <Style TargetType="ListViewItem">
                        <Setter Property="Focusable" Value="false"/>
                    </Style>
                </ListView.ItemContainerStyle>

                <!-- Hide Headers -->
                <ListView.Resources>
                    <Style TargetType="GridViewColumnHeader">
                        <Setter Property="Visibility" Value="Collapsed" />
                    </Style>
                </ListView.Resources>

                <ListView.View>
                    <GridView AllowsColumnReorder="False">

                        <GridViewColumn DisplayMemberBinding    = "{Binding Path=valueCurrent}" 
                                        Header                  = "Current"
                                        Width                   = "auto" />

                        <GridViewColumn DisplayMemberBinding    = "{Binding Path=valueTranslated}" 
                                        Header                  = "Translated"
                                        Width                   = "auto" />

                    </GridView>
                </ListView.View>

            </ListView>

            <!-- Title Similar -->
            <TextBlock Text         = "{x:Static res:Strings.vokDataGridEdit_Popup_Similar}"
                       Visibility   = "{Binding ShowHintsSimilar, RelativeSource={RelativeSource AncestorType=ccont:vokDataGridEdit}, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=collapsed}"
                       FontWeight   = "Bold"
                       Foreground   = "Black"
                       Margin       = "0, 5, 0, 2"/>

            <!-- Hints -->
            <ListView ItemsSource   = "{Binding ItemHintsSimilar, Mode=TwoWay, RelativeSource={RelativeSource AncestorType=ccont:vokDataGridEdit}}"
                      Visibility    = "{Binding ShowHintsSimilar, RelativeSource={RelativeSource AncestorType=ccont:vokDataGridEdit}, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=collapsed}"
                      Margin        = "5, 1, 1, 1">

                <!-- Prevent selection -->
                <ListView.ItemContainerStyle>
                    <Style TargetType="ListViewItem">
                        <Setter Property="Focusable" Value="false"/>
                    </Style>
                </ListView.ItemContainerStyle>

                <!-- Hide Headers -->
                <ListView.Resources>
                    <Style TargetType="GridViewColumnHeader">
                        <Setter Property="Visibility" Value="Collapsed" />
                    </Style>
                </ListView.Resources>

                <ListView.View>
                    <GridView AllowsColumnReorder="False">

                        <GridViewColumn DisplayMemberBinding    = "{Binding Path=valueCurrent}" 
                                        Header                  = "Current"
                                        Width                   = "auto" />

                        <GridViewColumn DisplayMemberBinding    = "{Binding Path=valueTranslated}" 
                                        Header                  = "Translated"
                                        Width                   = "auto" />

                    </GridView>
                </ListView.View>

            </ListView>

        </StackPanel>

    </Border>

</Popup>
wpf autolayout popup resize
1个回答
0
投票

[确定,最后我在解决项目中另一个启用GridViewListView时找到了解决方案。实际上,GridView引起了问题,因为当绑定集合中的元素发生更改时,它不会自动调整列的大小。

因此,我实现了一个Behavior,只要将ListView的集合绑定到更改,它将触发调整大小事件:

/// <summary>
/// Adds auto resizing to a ListView GridViews columns
/// </summary>
public class GridViewColumnAutoResizeBehavior : BehaviorBase<ListView>
{
    /// <summary>
    /// Setup the behavior
    /// </summary>
    protected override void OnAttached()
    {
        base.OnAttached();

        // Associate handler
        if (this.AssociatedObject?.Items is INotifyCollectionChanged notifyingCollection)
        {
            notifyingCollection.CollectionChanged += this.OnCollectionChanged;
        }
    }

    /// <summary>
    /// Handler to force resizing the columns
    /// </summary>
    private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
    {
        if (this.AssociatedObject.View is GridView gridView)
        {
            // Resize automatic columns
            foreach (GridViewColumn gridViewColumn in gridView.Columns.Where(column => double.IsNaN(column.Width)))
            {
                gridViewColumn.Width = gridViewColumn.ActualWidth;
                gridViewColumn.Width = double.NaN;
            }
        }
    }

    /// <summary>
    /// Clean-up the behavior
    /// </summary>
    protected override void OnCleanup()
    {
        // Clean-up handler
        if (this.AssociatedObject?.Items is INotifyCollectionChanged notifyingCollection)
        {
            notifyingCollection.CollectionChanged -= this.OnCollectionChanged;
        }

        base.OnCleanup();
    }
}

请确保使用实现了INotifyCollectionChanged的集合来附加行为。>>

代码使用自动分离行为,因此您需要适应所使用的基类,这应该很简单。

© www.soinside.com 2019 - 2024. All rights reserved.