2010-09-14 11 views
1

Je ne suis pas sûr de ce que je fais de mal, mais j'essaye d'aligner mon contrôle d'utilisateur avec le ColumnWidth de ma grille en utilisant DataBinding et DependencyProperties.WPF DataBinding: Grid ColumnDefinition Largeur de UserControl DependencyProperty

J'ai un GridView sur ma page de formulaire qui contient deux instances d'un contrôle utilisateur (adresse). L'adresse usercontrol contient un «entête» textlabel afin que je puisse nommer le contrôle d'utilisateur «adresse de bureau» ou «adresse postale» etc. et est formaté en utilisant son propre GridView. J'ai ajouté un DependencyProperty au contrôle de l'utilisateur appelé "HeaderWidth" qui est simplement un Int32. Le problème est que même avec les liaisons, les choses ne s'alignent pas. Je ne suis pas sûr de ce que je fais mal.

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}" /> 

Fondamentalement, je vais essayer pour aligner l'étiquette de texte de l'usercontrol avec la largeur de la première colonne d'inscription.

EDIT: Oh, et juste parce que je suis curieux: je mets un point d'arrêt de débogage et creusa profondément dans l'arbre interface utilisateur et suis arrivé à « En-tête » du AddressField (TextBlock) et le ActualWidth est pas 0,0 mais 73,9 ou quelque chose comme ça, mais l'interface utilisateur n'en tient pas compte, elle n'est toujours pas visible car la largeur est de 0.0.

Répondre

0

Il y a des moyens plus simples que vous connaissez :)

En termes simples Grid.IsSharedSizeScope="True" sur la grille dans la fenêtre principale (pas dans le contrôle) et SharedSizeGroup="someRandomName" sur toutes les colonnes que vous souhaitez partager la largeur - dans ce cas, seul la colonne que vous avez liée dans le contrôle utilisateur, c'est-à-dire remplacer la liaison par SharedSizeGroup. C'est tout! Toutes les colonnes ayant la même valeur SharedSizeGroup auront désormais la même taille, ce qui correspond à la taille de la plus grande d'entre elles.

Accordé, cela ne fonctionne que très bien avec le dimensionnement automatique, mais il semble que ce soit ce que vous voulez. Pour plus d'informations, vous pouvez rechercher here et here. Edit: pour ce que vous faisiez de mal, je suspecte que la colonne de la grille externe, étant dimensionnée à Auto, mais n'ayant pas de contenu à sa taille (parce que tous les contrôles s'étendaient sur plusieurs colonnes), a pris sur une largeur de zéro. Les liaisons ont ensuite été propagées aux contrôles utilisateur. Cependant, il y a beaucoup d'interactions compliquées, et je n'ai pas la totalité du XAML à juger, donc je peux me tromper.

+0

En fait, j'ai fini par changer le style de mes formulaires, donc je suppose que ce n'est plus un problème. Cependant, je soupçonne que votre réponse fonctionnerait probablement. Aussi, après y avoir pensé, je soupçonne que le problème est juste que ... j'essayais de lier à un contrôle utilisateur de la grille parent, ce qui déclencherait un redimensionnement ... quelque chose dans ce sens. –

+0

Oui, je l'ai testé avec les snippets que vous avez fournis pour m'assurer que je ne me trompe pas, donc ça marche, et c'est aussi une technique que j'ai utilisée avec succès. C'est vrai mais il y a plusieurs façons de résoudre ce problème :) –