Je cherche un moyen de trouver tous les contrôles de Window par leur type,
par exemple : trouver tous TextBoxes
trouver tous les contrôles implémentant une interface spécifique, etc.
Je cherche un moyen de trouver tous les contrôles de Window par leur type,
par exemple : trouver tous TextBoxes
trouver tous les contrôles implémentant une interface spécifique, etc.
Cela devrait faire l'affaire :
public static IEnumerable<T> FindVisualChilds<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj == null) yield return (T)Enumerable.Empty<T>();
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
DependencyObject ithChild = VisualTreeHelper.GetChild(depObj, i);
if (ithChild == null) continue;
if (ithChild is T t) yield return t;
foreach (T childOfChild in FindVisualChilds<T>(ithChild)) yield return childOfChild;
}
}
puis on énumère les contrôles comme suit
foreach (TextBlock tb in FindVisualChildren<TextBlock>(window))
{
// do something with tb here
}
Remarque : si vous essayez de faire fonctionner cette méthode et que vous constatez que votre fenêtre (par exemple) n'a pas d'enfants visuels, essayez d'exécuter cette méthode dans le gestionnaire d'événements Loaded. Si vous l'exécutez dans le constructeur (même après InitializeComponent()), les enfants visuels ne sont pas encore chargés, et cela ne fonctionnera pas.
Cela ne fonctionnera pas pour les enfants qui ne sont pas chargés mais présents. Par exemple, caché par Expander. Comment faire une énumération de tous les enfants ?
Que voulez-vous dire par "élément principal" ? Que dois-je écrire pour me connecter à mon formulaire mainwindow ?
Je comprends, dans la vue xaml j'ai dû définir le nom de la grille. <Grid Name="Anata_wa_yoru_o_shihai_suru_ai">here buttons</Grid>
et ensuite je pourrais utiliser Anata_wa_yoru_o_shihai_suru_ai.Children.OfType<myType>();
Cela ne répond pas à la question qui a été posée. Elle ne renvoie que les contrôles enfants d'un niveau de profondeur.
J'ai adapté la réponse de @Bryce Kahle pour suivre la suggestion de @Mathias Lykkegaard Lorenzen et utiliser LogicalTreeHelper
.
Ça a l'air de bien fonctionner ;)
public static IEnumerable<T> FindLogicalChildren<T> ( DependencyObject depObj ) where T : DependencyObject
{
if( depObj != null )
{
foreach( object rawChild in LogicalTreeHelper.GetChildren( depObj ) )
{
if( rawChild is DependencyObject )
{
DependencyObject child = (DependencyObject)rawChild;
if( child is T )
{
yield return (T)child;
}
foreach( T childOfChild in FindLogicalChildren<T>( child ) )
{
yield return childOfChild;
}
}
}
}
}
(Il ne vérifie toujours pas les contrôles de tabulation ou les grilles à l'intérieur de GroupBoxes comme mentionné par @Benjamin Berry & @David R respectivement). (J'ai également suivi la suggestion de @noonand et supprimé le redondant child != null)
Utilisez les classes d'aide VisualTreeHelper
o LogicalTreeHelper
en fonction des arbre qui vous intéressent. Elles fournissent toutes deux des méthodes pour obtenir les enfants d'un élément (bien que la syntaxe diffère un peu). J'utilise souvent ces classes pour trouver la première occurrence d'un type spécifique, mais vous pourriez facilement les modifier pour trouver tous les objets de ce type :
public static DependencyObject FindInVisualTreeDown(DependencyObject obj, Type type)
{
if (obj != null)
{
if (obj.GetType() == type)
{
return obj;
}
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject childReturn = FindInVisualTreeDown(VisualTreeHelper.GetChild(obj, i), type);
if (childReturn != null)
{
return childReturn;
}
}
}
return null;
}
+1 pour l'explication et le post mais Bryce Kahle a posté une fonction qui fonctionne parfaitement Merci
J'ai trouvé que la ligne, VisualTreeHelper.GetChildrenCount(depObj);
utilisé dans plusieurs exemples ci-dessus, ne renvoie pas un nombre non nul pour l'option GroupBox
es, en particulier, lorsque l GroupBox
contient un Grid
et le Grid
contient des éléments enfants. Je pense que cela peut être dû au fait que le GroupBox
n'est pas autorisé à contenir plus d'un enfant, et ceci est stocké dans sa section Content
la propriété. Il n'y a pas de GroupBox.Children
type de propriété. Je suis sûr que je n'ai pas fait cela très efficacement, mais j'ai modifié le premier exemple "FindVisualChildren" de cette chaîne comme suit :
public IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj != null)
{
int depObjCount = VisualTreeHelper.GetChildrenCount(depObj);
for (int i = 0; i <depObjCount; i++)
{
DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
if (child != null && child is T)
{
yield return (T)child;
}
if (child is GroupBox)
{
GroupBox gb = child as GroupBox;
Object gpchild = gb.Content;
if (gpchild is T)
{
yield return (T)child;
child = gpchild as T;
}
}
foreach (T childOfChild in FindVisualChildren<T>(child))
{
yield return childOfChild;
}
}
}
}
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
0 votes
Tant que nous sommes sur le sujet, ceci est également pertinent goo.gl/i9RVx
0 votes
J'ai également écrit un article de blog sur le sujet : Modifier un ControlTemplate à l'exécution