用户控件网格中的一行

时间:2012-03-08 17:04:42

标签: xaml user-controls grid

我有以下网格:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <!-- GridRow-Definition -->

    <Label Grid.Row="0" Grid.Column="0">FirstRow:</Label>
    <TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Binding_To_First_Row}" />

    <Label Grid.Row="1" Grid.Column="0">SecondRow:</Label>
    <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Binding_To_Second_Row}" />

    <!-- many more Label-TextBox-Rows -->
</Grid>

问题: 有没有办法创建一个包含Label和TextBox的UserControl,并以正确的方式正确对齐第一列?

2 个答案:

答案 0 :(得分:6)

答案是肯定的,这是可能的,但也许你应该使用DataGrid或带有DataTemplate的ItemsControl。

您问题的简单答案是,如果您需要不同网格中的网格列来同步其宽度,请使用 SharedSizeGroup 属性,例如:

<UserControl>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition SharedSizeGroup="column1" Width="auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
    </Grid>
</UserControl>

然后在父元素中使用 Grid.IsSharedSizeScope =“True”

<StackPanel Grid.IsSharedSizeScope="True">
    <local:UserControl1/>
    <local:UserControl1/>
</StackPanel>

这会同步在该范围内具有相同SharedSizeGroup的任何列(或行)(您可以拥有多个嵌套范围)。

答案 1 :(得分:0)

这将非常困难,因为usercontrol中的所有内容仅由该usercontrol呈现。拥有usercontrol的Grid对usercontrol的内容一无所知,我认为它应该保持这种状态。但是,您可以使用Prefix-,Text-和PrefixWidth-DependencyProperty创建自定义控件。

示例:

public class PrefixRow: Control
{
  static PrefixRow( )
  {
    DefaultStyleKeyProperty.OverrideMetadata( typeof( PrefixRow ) , new FrameworkPropertyMetadata( typeof( PrefixRow ) ) );
  }

  public string Text
  {
    get { return ( string )GetValue( TextProperty ); }
    set { SetValue( TextProperty , value ); }
  }
  public static readonly DependencyProperty TextProperty =
    DependencyProperty.Register( "Text" , typeof( string ) , typeof( PrefixRow ) , null );

  public double PrefixWidth
  {
    get { return ( double )GetValue( PrefixWidthProperty ); }
    set { SetValue( PrefixWidthProperty , value ); }
  }
  public static readonly DependencyProperty PrefixWidthProperty =
    DependencyProperty.Register( "PrefixWidth" , typeof( double ) , typeof( PrefixRow ) , null );

  public string Prefix
  {
    get { return ( string )GetValue( PrefixProperty ); }
    set { SetValue( PrefixProperty , value ); }
  }
  public static readonly DependencyProperty PrefixProperty = 
    DependencyProperty.Register( "Prefix" , typeof( string ) , typeof( PrefixRow ) , null );

}

在窗口中:

<Window x:Class="WPFApp.GridWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="GridWindow" Height="300" Width="300" xmlns:local="clr-namespace:WPFApp"
        >
<Window.Resources>
  <Style TargetType="{x:Type local:PrefixRow}">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type local:PrefixRow}">
        <Border Background="{TemplateBinding Background}"
                          BorderBrush="{TemplateBinding BorderBrush}"
                          BorderThickness="{TemplateBinding BorderThickness}">
          <Grid>
            <Grid.ColumnDefinitions>
              <ColumnDefinition Width="Auto"/>
              <ColumnDefinition Width="1*"/>
            </Grid.ColumnDefinitions>
            <TextBlock Text="{TemplateBinding Prefix}" Grid.Column="0" Width="{TemplateBinding PrefixWidth}"
                              VerticalAlignment="Center"/>
            <TextBox Text="{TemplateBinding Text}" Grid.Column="1"/>
          </Grid>
        </Border>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>
</Window.Resources>
<Grid>
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto"/>
    <RowDefinition Height="Auto"/>
    <RowDefinition Height="Auto"/>
    <RowDefinition Height="Auto"/>
    <RowDefinition Height="Auto"/>
  </Grid.RowDefinitions>
  <local:PrefixRow  PrefixWidth="{Binding ElementName=ColumnSlider, Path=Value}" Prefix="Row1" VerticalAlignment="Top" Text="test" Grid.Row="0"/>
  <local:PrefixRow  PrefixWidth="{Binding ElementName=ColumnSlider, Path=Value}" Prefix="Row1" VerticalAlignment="Top" Text="test" Grid.Row="1"/>
  <local:PrefixRow  PrefixWidth="{Binding ElementName=ColumnSlider, Path=Value}" Prefix="Row1" VerticalAlignment="Top" Text="test" Grid.Row="2"/>
  <local:PrefixRow  PrefixWidth="{Binding ElementName=ColumnSlider, Path=Value}" Prefix="Row1" VerticalAlignment="Top" Text="test" Grid.Row="3"/>
  <Slider x:Name="ColumnSlider" Minimum="10" Maximum="300" Value="50" Grid.Row="4"/>
</Grid>