WPF DataBinding:Grid ColumnDefinition Width to UserControl DependencyProperty

时间:2010-09-14 16:11:25

标签: wpf data-binding dependency-properties

我不确定我做错了什么,但我尝试使用DataBinding和DependencyProperties将我的用户控件与我的网格的ColumnWidth对齐。

我的表单页面上有一个GridView,它包含一个用户控件(地址)的两个实例。地址usercontrol包含一个textlabel“标题”,以便我可以将用户控件命名为“Office Address”或“Mailing Address”等,并使用它自己的GridView进行格式化。我在名为“HeaderWidth”的用户控件中添加了一个DependencyProperty,它只是一个Int32。问题是即使使用绑定,事情也不会对齐。我不确定我做错了什么。

AddressField.xaml

<UserControl x:Class="AddressField" x:Name="PART_AddressFieldControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         >
 <StackPanel Orientation="Horizontal">
  <Grid x:Name="StandardView">
   <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
   </Grid.RowDefinitions>
   <Grid.ColumnDefinitions>
    <ColumnDefinition Width="{Binding ElementName=PART_AddressFieldControl, Path=HeaderWidth}" />
    <ColumnDefinition Width="1*" />
    <ColumnDefinition Width="Auto" />
    <!-- ETC REMOVED FOR COMPACTNESS -->
   </Grid.ColumnDefinitions>

   <TextBlock Grid.Row="0" Grid.Column="0" HorizontalAlignment="Right" Text="{Binding ElementName=PART_AddressFieldControl, Path=Header}" />
   <TextBox Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="8" MinWidth="300" Text="{Binding Address1}" />
   <!-- ETC REMOVED FOR COMPACTNESS -->

  </Grid>
 </StackPanel>
</UserControl>

AddressField.cs

public partial class AddressField : UserControl
{
    static AddressField()
    {
        HeaderProperty = DependencyProperty.Register("Header", typeof(String), typeof(AddressField), new UIPropertyMetadata("Address:"));

        HeaderWidthProperty = DependencyProperty.Register("HeaderWidth", typeof(Int32), typeof(AddressField), new UIPropertyMetadata());

        ViewProperty = DependencyProperty.Register("View", typeof(AddressFieldView), typeof(AddressField), new UIPropertyMetadata(AddressFieldView.STANDARD));
    }

    public AddressField()
    {
        InitializeComponent();
    }

    public String Header
    {
        get { return (String)GetValue(HeaderProperty); }
        set { SetValue(HeaderProperty, value); }
    }
    public static readonly DependencyProperty HeaderProperty;

    public Int32 HeaderWidth
    {
        get { return (Int32)GetValue(HeaderWidthProperty); }
        set { SetValue(HeaderWidthProperty, value); }
    }
    public static readonly DependencyProperty HeaderWidthProperty;
}

RegistrationForm.xaml

<!-- ETC REMOVED FOR COMPACTNESS -->

<Grid.ColumnDefinitions>
 <ColumnDefinition Width="Auto" Name="FirstWidth" />
 <ColumnDefinition Width="Auto" />
 <!-- ... ETC ... -->
</Grid.ColumnDefinitions>

<vws:AddressField Grid.Row="1" Grid.Column="0" Grid.RowSpan="3" Grid.ColumnSpan="9" Header="Office Address:" DataContext="{Binding OfficeAddressVM}" HeaderWidth="{Binding ElementName=FirstWidth, Path=ActualWidth}" />
<vws:AddressField Grid.Row="4" Grid.Column="0" Grid.RowSpan="3" Grid.ColumnSpan="9" Header="Mailing Address:" DataContext="{Binding MailingAddressVM}" HeaderWidth="{Binding ElementName=FirstWidth, Path=ActualWidth}" />

基本上,我正在尝试将usercontrol的textlabel与registrationform第一列宽对齐。

修改的: 哦,只是因为我很好奇:我放了一个调试断点并深入挖掘UI树并得到了AddressField的“Header”(TextBlock),而且ActualWidth不是0.0但是73.9或类似的东西,但UI没有'考虑到这一点,它仍然是不可见的,因为宽度是0.0。

1 个答案:

答案 0 :(得分:0)

你知道的方法比较容易:)

只需将Grid.IsSharedSizeScope="True"放在主窗口(不在控件中)的网格上,并将SharedSizeGroup="someRandomName"放在要共享宽度的所有列上 - 在这种情况下,只列出您的列绑定在用户控件中,即用SharedSizeGroup替换绑定。而已!具有相同SharedSizeGroup值的任何列现在将具有相同的大小,这是其中最大的大小。

当然,它只适用于自动调整大小,但听起来就像你想要的那样。

有关详情,请查看herehere

编辑:关于你做错了什么,我怀疑外部网格列的大小是自动的,但没有自己的任何内容大小(因为所有控件都跨越多列),宽度为零。然后绑定传播到用户控件。虽然那里有很多复杂的交互,我没有整个XAML来判断,所以我可能错了。