Comment lier DataGridColumn.La visibilité?
J'ai un problème similaire au message suivant:
Silverlight DataGridTextColumn De Liaison De La Visibilité
J'ai besoin d'avoir une Colonne dans une Silverlight DataGrid être visible/effondré basée sur une valeur à l'intérieur d'un ViewModel. Pour accomplir cela, je tente de Lier la propriété de Visibilité à un ViewModel. Cependant j'ai vite découvert que la Visibilité de la propriété n'est pas une DependencyProperty, par conséquent, il ne peut pas être lié.
Pour résoudre ce problème, j'ai tenté de la sous-classe de ma propre DataGridTextColumn. Avec cette nouvelle classe, j'ai créé une DependencyProperty, qui finalement pousse les modifications apportées à la DataGridTextColumn.La visibilité de la propriété. Cela fonctionne bien, si je n'ai pas databind. Le moment où j'ai databind de ma nouvelle propriété, il ne parvient pas, avec un AG_E_PARSER_BAD_PROPERTY_VALUE exception.
public class MyDataGridTextColumn : DataGridTextColumn
{
#region public Visibility MyVisibility
public static readonly DependencyProperty MyVisibilityProperty =
DependencyProperty.Register("MyVisibility", typeof(Visibility), typeof(MyDataGridTextColumn), new PropertyMetadata(Visibility.Visible, OnMyVisibilityPropertyChanged));
private static void OnMyVisibilityPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var @this = d as MyDataGridTextColumn;
if (@this != null)
{
@this.OnMyVisibilityChanged((Visibility)e.OldValue, (Visibility)e.NewValue);
}
}
private void OnMyVisibilityChanged(Visibility oldValue, Visibility newValue)
{
Visibility = newValue;
}
public Visibility MyVisibility
{
get { return (Visibility)GetValue(MyVisibilityProperty); }
set { SetValue(MyVisibilityProperty, value); }
}
#endregion public Visibility MyVisibility
}
Voici un petit extrait de la XAML.
<DataGrid ....>
<DataGrid.Columns>
<MyDataGridTextColumn Header="User Name"
Foreground="#FFFFFFFF"
Binding="{Binding User.UserName}"
MinWidth="150"
CanUserSort="True"
CanUserResize="False"
CanUserReorder="True"
MyVisibility="{Binding Converter={StaticResource BoolToVisibilityConverter}, Path=ShouldShowUser}"/>
<DataGridTextColumn .../>
</DataGrid.Columns>
</DataGrid>
Quelques faits importants.
- Le Convertisseur est en effet défini ci-dessus dans les ressources locales.
- Le Convertisseur est correct, il est utilisé à plusieurs autres endroits dans la solution.
- Si je remplace l' {Binding} syntaxe de la MyVisibility propriété avec "Effondré" la Colonne n'est en fait disparaître.
- Si je crée un nouveau DependencyProperty (c'est à dire la chaîne Toto), et se lier à elle, je reçois la AG_E_PARSER_BAD_PROPERTY_VALUE exception.
Quelqu'un a une idée pourquoi cela ne fonctionne pas?
OriginalL'auteur Chris Mancini | 2009-06-25
Vous devez vous connecter pour publier un commentaire.
Voici la solution que j'ai trouvé avec l'aide d'un petit hack.
Tout d'abord, vous devez hériter de la grille de données.
La DataGridEx classe ajoute un nouveau DP pour cacher les colonnes en fonction de la x:Nom d'un DataGridColumn et de ses descendants.
À utiliser dans votre XAML:
Vous avez besoin de les ajouter à votre ViewModel ou quel que soit le contexte de données que vous utilisez.
À afficher, il vous suffit de retirer le nom correspondant dans la liste ou la recréer sans démasqués nom.
Fonctionne parfaitement avec Silverlight.. 🙂 merci Beaucoup de l'homme, vous avez fait ma journée..!!
OriginalL'auteur Stécy
J'ai une autre solution à ce problème qui utilise une approche similaire à la "Liaison" de la propriété que vous trouverez sur DataGridTextColumn. Depuis la colonne de classes sont DependencyObjects, vous ne pouvez pas directement databind, MAIS si vous ajoutez une référence à un FrameworkElement qui implémente INotifyPropertyChanged vous pouvez passer d'une liaison de données par le biais de l'élément, et ensuite utiliser une propriété de dépendance à informer la Colonne que la liaison de données a changé.
Une chose à noter est que le fait d'avoir la liaison sur la Colonne elle-même au lieu de la Grille va probablement dire que vous souhaitez utiliser un DataContextProxy pour accéder au champ que vous souhaitez lier la Visibilité (la liaison de colonne par défaut le champ d'application de la ItemSource).
}
J'ai eu à commenter l'avant-dernière ligne (n.MyVisibility = ...) d'effectuer par la suite bascule de travail, cependant.
Salut, il ne fonctionne pas pour mon cas. Décevant.
OriginalL'auteur GreatTall1
La colonne de grille de données hérite de DependencyObject au lieu de FrameworkElement. Dans WPF, ce serait pas grand chose... mais en silverlight, vous ne pouvez lier à FrameworkElement objets. Ainsi, vous obtenez le message d'erreur descriptif de AG_E_PARSER_BAD_PROPERTY_VALUE lorsque vous essayez.
désolé... je souhaite que je savais, mais c'est là que mes Silverlight connaissances se termine.
Ce n'est pas vrai. Silverlight permet la liaison à des propriétés de dépendance de DependencyObjects. Le problème est que la propriété de Visibilité des colonnes ne sont pas DependencyProperties.
OriginalL'auteur zachary
Je ne sais pas combien cela va aider, mais j'ai couru en l'absence de propriété de dépendance problème avec les données des colonnes de la grille de moi-même dans mon dernier projet. Ce que j'ai fait pour passer autour d'elle, était de créer un événement dans les colonnes de la grille de modèle d'affichage, puis, lorsque la grille est en cours de montage dans le client, l'utilisation d'une fermeture à vous abonner à la colonne de la grille de la colonne modèle de vue. Mon problème était d'environ de largeur. Il commence avec le point de vue de la classe du modèle de la colonne de la grille, qui ressemble à quelque chose comme ce pseudo-code:
Puis il y a le code qui assemble la grille:
Lorsque le contrôle datagrid est redimensionnée dans l'application, l'événement resize est ramassé et appelle la méthode de redimensionnement dans le viewmodel de la grille est lié. Cela appelle la méthode de redimensionnement de chaque colonne de la grille de modèle de vue. Les colonnes de la grille de modèle d'affichage pose alors la
ColumnResized
événement, dont la grille de données de colonne de texte est abonné, et c'est la largeur est mis à jour.Je me rends compte que ce n'est pas directement la résolution de votre problème, mais c'était une manière pour moi de pouvoir "lier" un modèle d'affichage d'une grille de données de la colonne quand il n'y a pas les propriétés de dépendance. La fermeture est une construction simple que bien encapsule le comportement que je voulais, et est tout à fait compréhensible pour quelqu'un qui vient derrière moi. Je pense que c'est pas trop dur à imaginer comment il pourrait être modifié pour faire face à la visibilité en train de changer. Vous pourriez même installer le gestionnaire d'événement dans l'événement load de la page/de contrôle de l'utilisateur.
OriginalL'auteur Geoff Bennett
Chris Mancini,
vous ne créez pas de liaison à la "Liaison" de la propriété des données de la colonne de la grille. Eh bien, vous écrivez "{Binding Utilisateur.Nom d'utilisateur}", mais il ne crée pas contraignant, car (comme il dit) colonne de grille de données n'héritent pas de FrameworkElement et n'a pas SetBinding méthode.
Donc, l'expression "{Binding Utilisateur.Nom d'utilisateur}" il suffit de crée la Liaison de l'objet et de l'affecter à la propriété de Liaison de la colonne (cette propriété est de type de Liaison).
Puis colonne de grille de données, tandis que génère des cellules de contenu (GenerateElement - méthode protégée) utilise cette Liaison objet pour définir la liaison sur les éléments générés (par exemple sur la propriété de Texte généré TextBlock) qui sont FrameworkElements
OriginalL'auteur
GreatTall1 la solution est grande, mais il faut un peu modifier pour le faire fonctionner.
OriginalL'auteur Andy Li
Noter que le problème n'est pas aussi simple que la "Visibilité" n'étant pas une propriété de dépendance. Dans un DataGrid les colonnes ne sont pas partie de visual arbre, de sorte que vous ne pouvez pas utiliser AncestorType même en WPF (ou Silverlight 5).
Voici un couple WPF liens connexes (veuillez commenter si l'une de ces travaux pour Silverlight - désolé de ne pas avoir le temps de tester maintenant)
A vraiment une belle explication du problème et les échecs de certaines solutions (et une solution intelligente):
http://tomlev2.wordpress.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/
Et un couple StackOverflow questions:
WPF Cacher DataGridColumn par l'intermédiaire d'une liaison
La liaison de propriété Visible d'un DataGridColumn en WPF DataGrid
OriginalL'auteur Simon_Weaver
Cela fonctionne sur une grille de données colonne modèle:
OriginalL'auteur Rob J
De votre MyDataGridTextColumn la classe, vous pouvez obtenir les environs de grille de données.
Puis, vous obtenez le ViewModel de la DataContext de la grille de données et ajouter un gestionnaire pour l'événement PropertyChanged de votre ViewModel. Dans le gestionnaire vous suffit de cocher le nom de la propriété et sa valeur et de modifier la Visibilité de la Colonne en conséquence.
Son pas tout à fait la meilleure solution, mais il devrait fonctionner 😉
OriginalL'auteur Andrej