首页 文章

自动将窗口宽度和高度设置为ItemsControl项

提问于
浏览
0

我有一个基本窗口,充当UserControls的通用容器 . 它按预期工作,除了宽度和高度似乎不是由子项的大小决定的(宽度和高度设置为auto,我希望) . 基本窗口的xaml如下:

<local:BaseView x:Class="Program.UI.Views.BaseWindowView"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
            xmlns:local="clr-namespace:Program.UI.Views"
            xmlns:converters="clr-namespace:Program.UI.Converters"
            xmlns:presenter="clr-namespace:Program.Presenter"
            xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
            mc:Ignorable="d" 
            ResizeMode="NoResize" WindowStyle="None"
            d:DesignHeight="300" d:DesignWidth="300" AllowsTransparency="True">
<i:Interaction.Triggers>
    <i:EventTrigger EventName="Closing">
        <presenter:EventToCommand Command="{Binding Mode=OneWay, Path=CloseWindow}" PassEventArgsToCommand="True"/>
    </i:EventTrigger>
</i:Interaction.Triggers>    
<local:BaseView.Resources>
    <ResourceDictionary>
        <converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
        <converters:SystemEventToForegroundColor x:Key="SystemEventToForegroundColor" />
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/Program;component/UI/Templates/Generic.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</local:BaseView.Resources>
<local:BaseView.Foreground>
    <SolidColorBrush Color="Black" Opacity="100"/>
</local:BaseView.Foreground>
<local:BaseView.Background>
    <SolidColorBrush Color="White" Opacity="0"/>
</local:BaseView.Background>
<Border BorderBrush="#FF838383" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderThickness="1" Height="auto" Width="auto" Margin="0,0,5,5">
    <Canvas Background="#E8F6F6" HorizontalAlignment="Stretch"  VerticalAlignment="Stretch" Height="auto" Width="auto">
        <Canvas.Effect>
            <DropShadowEffect RenderingBias="Quality" Opacity="0.3" ShadowDepth="3" BlurRadius="4"/>
        </Canvas.Effect>
        <DockPanel VerticalAlignment="Stretch" HorizontalAlignment="Stretch" 
                   Margin="0,0,0,0" x:Name="ReferenceInfo" Canvas.Left="0" Canvas.Top="0"
                   Width="{Binding ActualWidth, ElementName=InfoCanvas}"
                   Height="{Binding ActualHeight, ElementName=InfoCanvas}"
                   d:DesignWidth="294"
                   d:DesignHeight="294">

            <Grid Width="auto" Height="auto" HorizontalAlignment="Stretch"  VerticalAlignment="Stretch">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <Grid Grid.Row="0" Width="auto" HorizontalAlignment="Stretch" Height="30" VerticalAlignment="Top">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition />
                        <ColumnDefinition Width="30" />
                    </Grid.ColumnDefinitions>
                    <Border Grid.Column="0" BorderBrush="#FF838383" BorderThickness="0,0,0,1" Height="30" VerticalAlignment="Top">
                        <Label Style="{StaticResource WindowHeaderControlTitle}" MouseDown="Label_MouseDown"/>
                    </Border>
                    <Border Grid.Column="1" BorderBrush="#FF838383" BorderThickness="1,0,0,1">
                        <Label Style="{StaticResource WindowHeaderControlCloseLabel}" MouseEnter="Label_MouseEnter" MouseLeave="Label_MouseLeave" MouseLeftButtonUp="Label_MouseLeftButtonUp" MouseLeftButtonDown="Label_MouseLeftButtonDown" FontSize="14" FontFamily="Segoe UI Black" FontStretch="UltraExpanded" Content="X"/>
                    </Border>
                </Grid>
                <ItemsControl Grid.Row="1" Height="auto" Width="auto" ItemsSource="{Binding ChildView}"/>
            </Grid>

        </DockPanel>
    </Canvas>
</Border>

该视图是在Excel功能区按钮的单击事件上生成的,其代码隐藏为:

var childView = new DatapointDefinitionsView();
childView.DataContext = new DatapointDefinitionsViewModel();

ApplicationData.Presenter.ShowView<BaseWindowView>(
    new BaseWindowViewModel(childView, ApplicationData.Presenter), true);

ShowView代码是:

private BaseWindowView _windowView;
    public void ShowView<T>(BaseWindowViewModel viewModel, bool asModal) where T : BaseWindowView, new()
    {
        _windowView = new T
        {

            DataContext = viewModel,
            ShowInTaskbar = false,
            Title = viewModel.Caption,

        };
        //Width = viewModel.ChildView[0].Width,
        //Height = viewModel.ChildView[0].Height
        if (asModal)
        {
            _windowView.ShowDialog();
            _windowView = null;
        }
        else
        {
            _windowView.Show();
        }
    }

明确地将宽度和高度设置为子高度将宽度设置为指定的宽度,但不会影响高度 . 但是,即使它确实如此,这也不是一个令人满意的解决方案,因为它意味着值是固定的,并且如果用户控件尺寸发生变化则不会更新 .

还有另一种方法可以实现我想要的吗?

1 回答

  • 0

    所以我最终能够解决这个问题,具有所有所需的功能,如下所示:

    我将画布高度(在xaml中)绑定到DockPanel的高度 Height="{Binding ElementName=ReferenceInfo, Path=ActualHeight}"

    但是ItemsControl元素的宽度 Width="{Binding ElementName=ChildUserControl, Path=ActualWidth}"

    我从DockPanel中删除了高度和宽度,并根据@lokusking早先的建议重新启用了 SizeToContent="WidthAndHeight" 窗口属性 .

    为了启用 CanResizeWithGrip 功能(并使子usercontrol的内容相应地动态调整大小),我挂钩到窗口 SizeChanged 事件并添加了以下代码:

    private void BaseView_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            var window = sender as Window;
    
            if (ChildUserControl.HasItems)
            {
                var chlidControl = ChildUserControl.Items[0] as UserControl;
                var context = (BaseWindowViewModel)window.DataContext;
    
                // Ignore the first 3 resize events - these occur on view generation
                if (!context.InitialResizeComplete)
                    if (context.ResizeOperations < 3)
                    {
                        context.ResizeOperations++;
                        return;
                    }
    
                context.InitialResizeComplete = true;
    
                // Subtract all fixed size elements from window dimensions
                chlidControl.Width = window.ActualWidth - (OuterBorder.BorderThickness.Left + OuterBorder.BorderThickness.Right + OuterBorder.Margin.Right + OuterBorder.Margin.Left);
                chlidControl.Height = window.ActualHeight - (OuterBorder.BorderThickness.Top + OuterBorder.BorderThickness.Bottom + OuterBorder.Margin.Top + OuterBorder.Margin.Bottom + TaskBarGrid.Height);
            }
        }
    

    我还没有确定最初的3个调整大小操作的驱动因素 . 我的第一个猜测是初始化,然后是x,然后是y - 但是在反射时,它可能是1为baseview,1为basewindow,1为usercontrol . 如果是这种情况,那么使用这种方法附加的用户控件本身有多个视图可能会有问题,但我还没有测试 .

    希望有人能发现这很有用,感谢那些提供帮助的人 .

相关问题