Question

J'essaie de lier un DependancyProperty dans l'un de mes contrôles utilisateur à la propriété Width d'un Column dans un Grid.

J'ai un code similaire à celui-ci:

<Grid x:Name="MyGridName">
    <Grid.ColumnDefinitions>
        <ColumnDefinition x:Name="TitleSection" Width="100" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <Grid.RowDefinitions>...</Grid.RowDefinitions>

    <GridSplitter x:Name="MyGridSplitter" Grid.Row="0" Grid.Column="0" ... />
</Grid>

Dans un Usercontrol séparé, j'ai les éléments TitleWidth définis suivants

.
public static readonly DependencyProperty TitleWidthProperty = DependencyProperty.Register("TitleWidth", typeof(int), typeof(MyUserControl));

public int TitleWidth
{
    get { return (int)base.GetValue(TitleWidthProperty); }
    set { base.SetValue(TitleWidthProperty, value); }
}

Je crée des instances du code Usercontrol dans le code. J'ai donc une instruction de liaison similaire à celle-ci:

MyUserControl Cntrl = new MyUserControl(/* Construction Params */);
BindingOperations.SetBinding(Cntrl , MyUserControl.AnotherProperty, new Binding { ElementName = "objZoomSlider", Path = new PropertyPath("Value"), Mode = BindingMode.OneWay });
BindingOperations.SetBinding(Cntrl , MyUserControl.TitleWidthProperty, new Binding { ElementName = "TitleSection", Path = new PropertyPath("ActualWidth"), Mode = BindingMode.OneWay });
/* Other operations on Cntrl */

La première liaison définie fonctionne à merveille, bien que cela soit lié à un UIElement réel (dans ce cas un Slider), mais la liaison à & "TitleSection &"; (qui est la définition de colonne définie dans la grille) échoue. Mettre un point d'arrêt dans le code et faire une surveillance sur & Quot; TitleSection & Quot; renvoie l'objet attendu.

Je commence à soupçonner qu’un x: Name'd ColumnDefinition ne peut pas être lié. Quelqu'un peut-il suggérer comment je pourrais peut-être me lier à la largeur changeante de la première colonne de ma grille?

EDIT # 1 - Répondre aux commentaires

La liaison de données 'échoue' dans le sens où, avec un point d'arrêt défini sur le séparateur pour la propriété Window_Loaded et en utilisant le contrôle GridSplitter pour redimensionner la première colonne, le point d'arrêt n'est jamais atteint. De plus, le code que j'attendrais d'être déclenché lorsque les modifications de DependancyProperty TitleSection ne sont pas exécutées.

Le contrôle utilisateur est en cours de création et ajouté à un Stackpanel dans la grille dans la fonction 100. Je m'attendrais à ce que la grille ait été rendue au moment de la construction des contrôles Usercontrols. L’élément x: Name'd <=> est certainement contrôlable et a une valeur <=> lorsqu’il est en cours de construction / avant que la liaison ne se produise.

EDIT # 2 - Peut-être quelque chose à voir avec cela?

J'ai scruté les pages MSDN de la documentation Grid ColumnDefinition et j'ai rencontré GridLength () , mais je ne comprends pas trop comment utiliser cela dans une expression de liaison. Je ne peux pas utiliser le convertisseur GridLengthConverter associé en tant que convertisseur dans le code de liaison car il ne provient pas de IValueConverter.

Je suis plutôt orienté vers la propriété ActualWidth de l’une des cellules de l’objet Grid. Cela ne semble pas aussi simple que de se lier à la définition de colonne, mais pour le moment, je ne peux pas le faire fonctionner.

Était-ce utile?

La solution

Eh bien, j'ai un peu de mal à fonctionner, je vais expliquer comment pour les générations futures:

J'ai essentiellement une grille à 2 colonnes et à plusieurs lignes avec un séparateur aligné à droite dans la première colonne afin que l'utilisateur puisse le redimensionner si le contenu qu'il contient nécessite davantage d'espace. Pour compliquer les choses, un contrôle utilisateur est chargé par programme dans certaines des lignes qui possède un columnSpan de 2 à des fins de rendu (le contenu "se fond d'une cellule à l'autre".

Lorsque la première colonne est redimensionnée, il faut que cela soit reflété dans le contrôle utilisateur. J'ai d'abord essayé de me lier à ColumnDefinition, mais ce n'était pas vraiment jouer au ballon.

Comment je l'ai corrigé / approuvé

Dans une cellule de rechange de la première colonne, j'ai ajouté un <Label> avec un x: Name pour le rendre accessible. Comme il est dans une cellule, il a les propriétés par défaut de 'Stretch' et remplit complètement la cellule. Il est redimensionné à mesure que la colonne est redimensionnée à l'aide du séparateur. La liaison à la propriété ActualWidth du libellé signifie que les modifications apportées à la taille de la colonne sont communiquées à DependancyProperty dans le contrôle utilisateur de columnSpanned correctement.

Pensées

Évidemment, bien que ColumnDefinition ait une propriété PropertyChanged lorsqu’elle change, elle ne semble pas déclencher l’événement <=> en interne (ou c’est ma meilleure supposition). C’est peut-être un bogue, ou de par leur conception, mais pour moi, cela signifie que j’ai dû utiliser une solution moins propre.

Autres conseils

Avez-vous essayé de configurer la liaison dans xaml, les opérations suivantes devraient fonctionner pour vous.

<ColumnDefinition 
    x:Name="TitleSection" 
    Width="{Binding 
                Path=TitleWidth, 
                RelativeSource={RelativeSource AncestorType=MyUserControl}}" 
    />

Sinon, si vous regardez le code de liaison que vous avez fourni, cela ne me convient pas du tout, la cible de la liaison devrait être la colonne de la grille et la source devrait être votre propriété de dépendance.

Le code équivalent pour le xaml ci-dessus est

BindingOperations.SetBinding(TitleSection, ColumnDefinition.WidthProperty,
    new Binding()
    {
        RelativeSource= new RelativeSource(RelativeSourceMode.FindAncestor, typeof(MyUserControl),1),
        Path = new PropertyPath("TitleWidth"),
    });

Sur une note connexe, l'utilisation d'un GridSplitter et la liaison de la propriété Width s'excluent mutuellement. Dès que vous redimensionnez la colonne à l'aide du séparateur, votre liaison sera remplacée par la valeur du séparateur.

Ceci est similaire à ce que vous verriez en mettant à jour une propriété qui est la cible d'une liaison. Lorsque vous définissez la valeur des cibles directement dans le code, vous remplacez essentiellement l'objet de liaison par la valeur que vous fournissez.

ColumnDefinition.Width n’est pas un entier, c’est un GridLength. Vous ne pouvez pas lier directement GridLength à Integer, vous avez besoin d’un convertisseur.

C’est également la raison pour laquelle vous ne pouvez lier aucune propriété Width (double) d’un contrôle à une propriété Width d’un ColumnDefinition (GridLength) sans convertisseur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top