2016-10-22 59 views
0

[UWP]大家好,我正在努力与一个用户控件,我创建我自己的字段容器(groupbox)里面我发布不同的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> 

我的代码Bheind用户控件:

[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> 

这是我的结果:

enter image description here

编辑:

原谅我,但我错了粘贴代码和图像。我纠正: 我的用法如下:

   <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> 

,这我的结果: enter image description here

编辑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在设备上运行时将二次探底组。

回答

2

StackPanel中删除HorizontalAlignment="Left",其中包含InnterContent中的两个文本框。

<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:绑定,而不是直接:

<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> 

EDIT 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之前。

+0

感谢您的回复,但我只是纠正了这个问题,我错了粘贴示例 – Brux88

+0

感谢澄清,但有一种方法来保持StackPanel? 我会解释,因为我必须管理VisualStateManager。 我编辑我的问 – Brux88