【问题标题】:User Control Content Control does not fill用户控件内容控件不填
【发布时间】:2016-10-22 09:51:33
【问题描述】:

[UWP] 大家好,我正在为用户控件而苦苦挣扎,我在其中创建了自己的字段容器(组框),在其中发布了不同的 StackPanel,并在文本框内。

但是当我插入 StackPanel 时,您并没有有效地填充空白空间。我尝试在各种选项中设置 strecth,但没有。

这是我的用户控件的代码:

<UserControl Name="groupBoxUC"
x:Class="AgendaUWP.Common.CustomControls.GroupBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:AgendaUWP.Common.CustomControls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:interop="using:Windows.UI.Xaml.Interop"
mc:Ignorable="d"
d:DesignHeight="200"
d:DesignWidth="300">

    <StackPanel x:Name="myStackPanel"  BorderThickness="1" BorderBrush="Gray" Orientation="Vertical">
    <StackPanel Margin="10 0 0 0"   HorizontalAlignment="Left" >
        <Border  Background="{StaticResource secondaryColor}"  Height="5" Width="{Binding ActualWidth, ElementName=HeaderText}"/>
        <TextBlock x:Name="HeaderText" FontSize="18" FontWeight="ExtraLight"   Text="{x:Bind Header,Mode=TwoWay}"/>
    </StackPanel>

    <ContentControl Padding="10 20 10 20"  Content="{Binding InnerContent,ElementName=groupBoxUC}" HorizontalAlignment="Stretch" 
            VerticalAlignment="Stretch" 
            HorizontalContentAlignment="Stretch" 
            VerticalContentAlignment="Stretch" />
</StackPanel>

我的代码隐藏用户控件:

  [ContentProperty(Name = "InnerContent")]
public sealed partial class GroupBox : UserControl
{
    internal static readonly  DependencyProperty InnerContentProperty =
   DependencyProperty.Register("InnerContent", typeof(object), typeof(GroupBox), new PropertyMetadata(null));

    internal static readonly DependencyProperty HeaderProperty =
  DependencyProperty.Register("Header", typeof(string), typeof(GroupBox), new PropertyMetadata(null));


    public GroupBox()
    {
        this.InitializeComponent();
    }

    public object InnerContent
    {
        get { return (object)GetValue(InnerContentProperty); }
        set { SetValue(InnerContentProperty, value); }
    }
    public string Header
    {
        get { return (string) GetValue(HeaderProperty); }
        set { SetValue(HeaderProperty, value); }
    }

}

这就是我的使用方式:

<CustomControls:GroupBox x:Name="grpCoordinate" Header="Coordinate" Margin="30,40,30,0" >
                <StackPanel    HorizontalAlignment="Left">
                    <TextBox Header="Longitudine:" Text="{x:Bind ViewModel.Cliente.Longitudine, Mode=TwoWay}"  HorizontalAlignment="Stretch" />

                    <TextBox Header="Latitudine:" Text="{x:Bind ViewModel.Cliente.Latitudine, Mode=TwoWay}"  HorizontalAlignment="Stretch" />


                </StackPanel>

            </CustomControls:GroupBox>

这是我的结果:

编辑:

对不起,我错误地粘贴了代码和图像。我更正: 我的用法如下:

                <CustomControls:GroupBox x:Name="grpDatiAnagrafici" Header="Dati Anagrafici" VerticalAlignment="Top" Margin="30,0,30,0" Grid.Column="0" Grid.Row="0" >

                <StackPanel x:Name="stkDatiAnagrafici" Orientation="Horizontal">
                    <StackPanel Padding="0 0 20 0">
                        <TextBox  Header="Codice:" Text="{x:Bind ViewModel.Cliente.Codice, Mode=TwoWay}" IsReadOnly="True" IsEnabled="False"/>
                        <TextBox  Header="Ragione Sociale:" Text="{x:Bind ViewModel.Cliente.RagioneSociale, Mode=TwoWay}"  />
                        <TextBox Header="Nome:" Text="{x:Bind ViewModel.Cliente.Nome, Mode=TwoWay}" />
                        <TextBox Header="Cognome:" Text="{x:Bind ViewModel.Cliente.Cognome, Mode=TwoWay}" />
                    </StackPanel>
                    <StackPanel>
                        <TextBox Header="Indirizzo:" Text="{x:Bind ViewModel.Cliente.Indirizzo, Mode=TwoWay}"  />
                        <TextBox Header="Comune:" Text="{x:Bind ViewModel.Cliente.Comune, Mode=TwoWay}" />
                        <TextBox Header="Cap:" Text="{x:Bind ViewModel.Cliente.Cap, Mode=TwoWay}" />
                        <TextBox Header="Provincia:" Text="{x:Bind ViewModel.Cliente.Provincia, Mode=TwoWay}" />

                    </StackPanel>
                </StackPanel>
            </CustomControls:GroupBox>

这是我的结果:

编辑 2:

感谢澄清,但有办法保留 StackPanel 吗? 我会解释,因为我必须管理 VisualStateManager:

    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="WindowStates">
            <VisualState x:Name="WideState">
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="600" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="stkDatiAnagrafici.Orientation" Value="Horizontal" />        
                </VisualState.Setters>
            </VisualState>
            <VisualState x:Name="NarrowState">
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="0" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="stkDatiAnagrafici.Orientation" Value="Vertical" />
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>

因为如果我使用网格,我还必须指定 Grid.Row 在设备上运行时放置第二个底部组。

【问题讨论】:

    标签: xaml user-controls uwp windows-10-universal


    【解决方案1】:

    从包含InnterContent 内的两个文本框的StackPanel 中删除HorizontalAlignment="Left"

    <CustomControls:GroupBox x:Name="grpCoordinate" Header="Coordinate" Margin="30,40,30,0">
        <StackPanel> <!-- Removed HorizontalAlignment="Left" from here -->
            <TextBox Header="Longitudine:" Text="{x:Bind ViewModel.Cliente.Longitudine, Mode=TwoWay}"  HorizontalAlignment="Stretch" />
            <TextBox Header="Latitudine:" Text="{x:Bind ViewModel.Cliente.Latitudine, Mode=TwoWay}"  HorizontalAlignment="Stretch" />
        </StackPanel>
    </CustomControls:GroupBox>
    

    另外,这不是必需的,但我会将ContentControl 更改为ContentPresenter。您可以避免 ElementName 绑定,而直接使用 x:Bind:

    <ContentPresenter Padding="10 20 10 20" Content="{x:Bind InnerContent}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
    

    编辑

    水平的StackPanel 无法在每个子元素之间分配可用空间,它只是尊重每个子元素的DesiredSize。您需要改用Grid

    <Grid x:Name="stkDatiAnagrafici">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
    
        <StackPanel Grid.Column="0" Padding="0 0 20 0">
            <TextBox Header="Codice:" Text="{x:Bind ViewModel.Cliente.Codice, Mode=TwoWay}" IsReadOnly="True" IsEnabled="False"/>
            <TextBox Header="Ragione Sociale:" Text="{x:Bind ViewModel.Cliente.RagioneSociale, Mode=TwoWay}"  />
            <TextBox Header="Nome:" Text="{x:Bind ViewModel.Cliente.Nome, Mode=TwoWay}" />
            <TextBox Header="Cognome:" Text="{x:Bind ViewModel.Cliente.Cognome, Mode=TwoWay}" />
        </StackPanel>
        <StackPanel Grid.Column="1">
            <TextBox Header="Indirizzo:" Text="{x:Bind ViewModel.Cliente.Indirizzo, Mode=TwoWay}"  />
            <TextBox Header="Comune:" Text="{x:Bind ViewModel.Cliente.Comune, Mode=TwoWay}" />
            <TextBox Header="Cap:" Text="{x:Bind ViewModel.Cliente.Cap, Mode=TwoWay}" />
            <TextBox Header="Provincia:" Text="{x:Bind ViewModel.Cliente.Provincia, Mode=TwoWay}" />
        </StackPanel>
    </Grid>
    

    编辑 2

    您仍然可以使用Grid,您只需要在您的视觉状态中设置正确的属性以使其具有正确的外观。您无法使用StackPanel,因为它不会分配其子项的宽度。

    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="WindowStates">
            <VisualState x:Name="WideState">
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="600"/>
                </VisualState.StateTriggers>
            </VisualState>
            <VisualState x:Name="NarrowState">
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="0"/>
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="stack1.Padding" Value="0"/>
                    <Setter Target="stack2.Padding" Value="0"/>
                    <Setter Target="stack2.(Grid.Column)" Value="0"/>
                    <Setter Target="stack2.(Grid.Row)" Value="1"/>
                    <Setter Target="stkDatiAnagrafici.ColumnDefinitions[1].Width" Value="0"/>
                    <Setter Target="stkDatiAnagrafici.RowDefinitions[1].Height" Value="*"/>
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
    
    <CustomControls:GroupBox x:Name="grpDatiAnagrafici" Header="Dati Anagrafici" VerticalAlignment="Top" Margin="30,0,30,0" Grid.Column="0" Grid.Row="0" >
        <Grid x:Name="stkDatiAnagrafici">
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition Height="0"/>
            </Grid.RowDefinitions>
    
            <StackPanel x:Name="stack1" Grid.Column="0" Padding="0 0 10 0">
                <TextBox Header="Codice:" IsReadOnly="True" IsEnabled="False"/>
                <TextBox Header="Ragione Sociale:"/>
                <TextBox Header="Nome:"/>
                <TextBox Header="Cognome:"/>
            </StackPanel>
            <StackPanel x:Name="stack2" Grid.Column="1" Padding="10 0 0 0">
                <TextBox Header="Indirizzo:"/>
                <TextBox Header="Comune:"/>
                <TextBox Header="Cap:"/>
                <TextBox Header="Provincia:"/>
            </StackPanel>
        </Grid>
    </CustomControls:GroupBox>
    

    编辑 2B

    如果您想要一个更通用的解决方案(超过 2 列),那么您始终可以编写自己的自定义 StackPanel 以均匀分配空间:

    class FilledStackPanel : StackPanel
    {
        protected override Size MeasureOverride(Size availableSize)
        {
            var childSize = Orientation == Orientation.Horizontal ?
                new Size(availableSize.Width / Children.Count, availableSize.Height) :
                new Size(availableSize.Width, availableSize.Height / Children.Count);
    
            double alongAxis = 0;
            double crossAxis = 0;
    
            foreach (var child in Children)
            {
                child.Measure(childSize);
    
                if (Orientation == Orientation.Horizontal)
                {
                    alongAxis += child.DesiredSize.Width;
                    crossAxis = Math.Max(crossAxis, child.DesiredSize.Height);
                }
                else
                {
                    alongAxis += child.DesiredSize.Height;
                    crossAxis = Math.Max(crossAxis, child.DesiredSize.Width);
                }
            }
    
            return Orientation == Orientation.Horizontal ?
                new Size(alongAxis, crossAxis) :
                new Size(crossAxis, alongAxis);
        }
    
        protected override Size ArrangeOverride(Size finalSize)
        {
            var childSize = Orientation == Orientation.Horizontal ?
                new Size(finalSize.Width / Children.Count, finalSize.Height) :
                new Size(finalSize.Width, finalSize.Height / Children.Count);
    
            double alongAxis = 0;
    
            foreach (var child in Children)
            {
                if (Orientation == Orientation.Horizontal)
                {
                    child.Arrange(new Rect(alongAxis, 0, childSize.Width, childSize.Height));
                    alongAxis += childSize.Width;
                }
                else
                {
                    child.Arrange(new Rect(0, alongAxis, childSize.Width, childSize.Height));
                    alongAxis += childSize.Height;
                }
            }
    
            return finalSize;
        }
    }
    

    现在您不需要使用Grid,可以使用FilledStackPanel 代替之前的StackPanel

    【讨论】:

    • 感谢回复,不过我刚刚更正了问题,我贴错了例子
    • 感谢澄清,但有办法保留 StackPanel?我会解释,因为我必须管理 VisualStateManager。我编辑我的问题
    猜你喜欢
    • 1970-01-01
    • 2010-12-27
    • 2011-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多