【问题标题】:UserControl child fill WindowUserControl 子填充窗口
【发布时间】:2016-03-15 14:52:41
【问题描述】:

我有一个用户控件,它是 wpf 窗口的一部分。

<Window>
    <Grid>
        <!--some other display elements would be here-->
        <local:MyUserControl x:Name="Foo" Padding="0,42,0,50"/>
    </Grid>
</Window>

在 MyUserControl 中,我有一个元素,它通常是隐藏的画廊,但当它可见时,它应该会填满整个屏幕。

<UserControl>
    <Grid>
        <!--main display elements would be here-->
        <Grid Name="Gallery" Visibility="Hidden">
            <Rectangle Fill="Black" Opacity="0.75"/>
            <TextBlock Name="GalleryLabel" Foreground="White" TextAlignment="Center">Current Image Title</TextBlock>
            <Button Name="CloseGallery" Style="{DynamicResource WhiteTextButton}" Margin="0,0,0,0" Height="25" VerticalAlignment="Top" HorizontalAlignment="Right" Width="25" Click="GalleryClose_OnClick">X</Button>
            <Image Name="GalleryImage" Margin="25"/>
        </Grid>
    </Grid>
</UserControl>

如何设置 Gallery 以填充整个 Window 而不仅仅是 UserControl?

我可以通过将 Margin="0,-42,0,-50" 添加到 Gallery 来使其工作,但我不喜欢该解决方案。我宁愿做一些不涉及在 UserControl 中硬编码值的事情,这样我就可以更灵活地使用它。

通常它看起来像: 其中绿色的 Foo 区域是 MyUserControl,窗口中其余的东西是其他元素。

在某些时候,我有一个画廊显示一个图像,它应该填满整个屏幕,如: 它应该填满整个屏幕并有一个黑色的不透明覆盖层,并在覆盖层顶部显示一个图像。

【问题讨论】:

    标签: wpf user-controls window wpf-controls


    【解决方案1】:

    删除填充...

    你可以使用:

     <local:MyUserControl x:Name="Foo" VerticalAlignment="Stretch" HorizontalAligment="Stretch"/>
    

    编辑

    我可能承认我仍然不确定你想要什么。但我做了一些和你在图片中展示的一样的东西。但请注意,这是一个基于意见的问题,答案是我的意见,有很多方法可以实现这一目标。而这只是其中之一:

    主窗口

    <Window x:Class="MyProject.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:myProject="clr-namespace:MyProject"
        Title="MainWindow" >
    
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="50"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
    
        <Border Background="Gainsboro" Grid.Row="0">
            <StackPanel Orientation="Horizontal">
                <Button Content="Show gallery" Width="100" Margin="10"/>
                <Button Content="Do something else" Width="150" Margin="10"/>
            </StackPanel>
        </Border>
    
        <myProject:SomeOtherStuff Grid.Row="1" />
    
        <Border Grid.Row="2" Background="Gainsboro">
            <StackPanel Orientation="Horizontal">
                <Label Content="Buttom area, can be used for something else"/>
            </StackPanel>
        </Border>
    
        <myProject:GalleryUserControl x:Name="GalleryUserControl" Grid.Row="0" Grid.RowSpan="3" Visibility="Hidden"/>
    </Grid>
    

    SomeOtherStuff 用户控件

    <UserControl x:Class="MyProject.SomeOtherStuff"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid Background="Green">
        <Label VerticalAlignment="Center" HorizontalAlignment="Center" Content="Foo" FontSize="30" FontFamily="Verdana"/>
    </Grid>
    

    图库用户控件

    <UserControl x:Class="XamDataGrid.GalleryUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="500" Width="800">
    <Grid Background="#99000000">
        <TextBlock Text="Currect image title" Foreground="White" TextAlignment="Center" VerticalAlignment="Top" HorizontalAlignment="Stretch"/>
        <Button Name="CloseGallery"  Margin="0,0,0,0" Content="X" Height="25" VerticalAlignment="Top" HorizontalAlignment="Right" Width="25" Click="GalleryClose_OnClick"/>
        <Image Margin="30"/>
    </Grid>
    

    【讨论】:

    • 现在的问题是 MyUserControl 覆盖了窗口中的其他元素
    • 这不是你想要的吗???我们看不到你那里还有什么其他元素。你要求让它填满整个窗口
    • 没有。我在窗口中有&lt;!--some other display elements would be here--&gt;,因为我拥有的实际元素可能没有帮助,而且它们可能会发生变化。我专门要求画廊填满窗口,而不是其他任何东西。
    • 你必须更清楚,因为现在还不清楚你想要什么。什么是“画廊”?根据您的代码,它是您的用户控件内的网格​​,它填充了整个用户控件。这就是为什么我假设您希望 UserControl 填充整个窗口。我可以继续猜测或假设,但可能会添加绘图或更多解释。
    【解决方案2】:

    Adorner 最适合您。因为它漂浮在其他所有事物之上,并且也在 VisualTree 之外。

    用户控件2

      <UserControl2 ...>
       <Grid>
            <Grid Background="#FF709FA6" Opacity="0.3" Width="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}}"
                 Height="{Binding ActualHeight, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}}">
            </Grid>
            <Grid Width="600" Height="700">
                <Grid.Background>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FF37DAEA" Offset="0"/>
                        <GradientStop Color="#FFE84242" Offset="1"/>
                    </LinearGradientBrush>
                </Grid.Background>
                <!-- Gallery controls -->
                <Button Content="Welcome to Gallery" HorizontalAlignment="Left" IsHitTestVisible="True" Margin="112,126,0,0" VerticalAlignment="Top" Height="68" FontSize="48" Click="Button_Click_1"/>
                <TextBlock HorizontalAlignment="Left" Margin="83,42,0,0" TextWrapping="Wrap" Text="UserControl2" VerticalAlignment="Top" Foreground="#FF1B0D0D"/>
            </Grid>
        </Grid>
      </UserControl2>
    

    用户控件1

    代码:

    public partial class UserControl1 : UserControl
        {
            public UserControl1()
            {
                InitializeComponent();
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                // get root Window
                DependencyObject current = LogicalTreeHelper.GetParent(this);
                while (!(current is Window))
                    current = LogicalTreeHelper.GetParent(current);
    
                Window root = current as Window;
    
                IEnumerable children = LogicalTreeHelper.GetChildren(root);
                Panel p = null;
                foreach (var child in children)
                {
                    p = child as Panel; // get first container panel in Window
                    break;
                }
    
                // Create UserControl2 to add to the adorner
                UserControl2 ctrlGallery = new UserControl2();
    
                AdornerLayer layer = AdornerLayer.GetAdornerLayer(p);
                GalleryAdorner adorner = new GalleryAdorner(p, ctrlGallery);
                layer.Add(adorner);
            }
        }
    
    public class GalleryAdorner : Adorner
        {
            private Control _child;
            VisualCollection collection;
    
            public GalleryAdorner(UIElement elem, Control child)
                : base(elem)
            {
                collection = new VisualCollection(this);
                _child = child;
                collection.Add(_child);
            }
    
            protected override int VisualChildrenCount
            {
                get
                {
                    return 1;
                }
            }
    
            protected override Visual GetVisualChild(int index)
            {
                if (index != 0) throw new ArgumentOutOfRangeException();
                return collection[0];
            }
    
            protected override Size MeasureOverride(Size constraint)
            {
                _child.Measure(constraint);
                return _child.DesiredSize;
            }
    
            protected override Size ArrangeOverride(Size finalSize)
            {
                _child.Arrange(new Rect(new Point(0, 0), finalSize));
                return new Size(_child.ActualWidth, _child.ActualHeight);
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-09
      • 2013-07-19
      • 2013-08-13
      • 2021-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多