Wpf как найти элемент по имени

Asked
14 years, 2 months ago

Viewed
391k times

I need to search a WPF control hierarchy for controls that match a given name or type. How can I do this?

Shog9's user avatar

Shog9

156k34 gold badges229 silver badges234 bronze badges

asked Mar 11, 2009 at 21:08

alex2k8's user avatar

0

I combined the template format used by John Myczek and Tri Q’s algorithm above to create a findChild Algorithm that can be used on any parent. Keep in mind that recursively searching a tree downwards could be a lengthy process. I’ve only spot-checked this on a WPF application, please comment on any errors you might find and I’ll correct my code.

WPF Snoop is a useful tool in looking at the visual tree — I’d strongly recommend using it while testing or using this algorithm to check your work.

There is a small error in Tri Q’s Algorithm. After the child is found, if childrenCount is > 1 and we iterate again we can overwrite the properly found child. Therefore I added a if (foundChild != null) break; into my code to deal with this condition.

/// <summary>
/// Finds a Child of a given item in the visual tree. 
/// </summary>
/// <param name="parent">A direct parent of the queried item.</param>
/// <typeparam name="T">The type of the queried item.</typeparam>
/// <param name="childName">x:Name or Name of child. </param>
/// <returns>The first parent item that matches the submitted type parameter. 
/// If not matching item can be found, 
/// a null parent is being returned.</returns>
public static T FindChild<T>(DependencyObject parent, string childName)
   where T : DependencyObject
{    
  // Confirm parent and childName are valid. 
  if (parent == null) return null;

  T foundChild = null;

  int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
  for (int i = 0; i < childrenCount; i++)
  {
    var child = VisualTreeHelper.GetChild(parent, i);
    // If the child is not of the request child type child
    T childType = child as T;
    if (childType == null)
    {
      // recursively drill down the tree
      foundChild = FindChild<T>(child, childName);

      // If the child is found, break so we do not overwrite the found child. 
      if (foundChild != null) break;
    }
    else if (!string.IsNullOrEmpty(childName))
    {
      var frameworkElement = child as FrameworkElement;
      // If the child's name is set for search
      if (frameworkElement != null && frameworkElement.Name == childName)
      {
        // if the child's name is of the request name
        foundChild = (T)child;
        break;
      }
    }
    else
    {
      // child element found.
      foundChild = (T)child;
      break;
    }
  }

  return foundChild;
}

Call it like this:

TextBox foundTextBox = 
   UIHelper.FindChild<TextBox>(Application.Current.MainWindow, "myTextBoxName");

Note Application.Current.MainWindow can be any parent window.

John Cummings's user avatar

answered Nov 18, 2009 at 23:42

CrimsonX's user avatar

CrimsonXCrimsonX

9,0389 gold badges41 silver badges52 bronze badges

10

You can also find an element by name using FrameworkElement.FindName(string).

Given:

<UserControl ...>
    <TextBlock x:Name="myTextBlock" />
</UserControl>

In the code-behind file, you could write:

var myTextBlock = (TextBlock)this.FindName("myTextBlock");

Of course, because it’s defined using x:Name, you could just reference the generated field, but perhaps you want to look it up dynamically rather than statically.

This approach is also available for templates, in which the named item appears multiple times (once per usage of the template).

John Cummings's user avatar

answered Sep 25, 2009 at 12:48

Drew Noakes's user avatar

Drew NoakesDrew Noakes

298k163 gold badges677 silver badges739 bronze badges

3

You can use the VisualTreeHelper to find controls. Below is a method that uses the VisualTreeHelper to find a parent control of a specified type. You can use the VisualTreeHelper to find controls in other ways as well.

public static class UIHelper
{
   /// <summary>
   /// Finds a parent of a given item on the visual tree.
   /// </summary>
   /// <typeparam name="T">The type of the queried item.</typeparam>
   /// <param name="child">A direct or indirect child of the queried item.</param>
   /// <returns>The first parent item that matches the submitted type parameter. 
   /// If not matching item can be found, a null reference is being returned.</returns>
   public static T FindVisualParent<T>(DependencyObject child)
     where T : DependencyObject
   {
      // get parent item
      DependencyObject parentObject = VisualTreeHelper.GetParent(child);

      // we’ve reached the end of the tree
      if (parentObject == null) return null;

      // check if the parent matches the type we’re looking for
      T parent = parentObject as T;
      if (parent != null)
      {
         return parent;
      }
      else
      {
         // use recursion to proceed with next level
         return FindVisualParent<T>(parentObject);
      }
   }
}

Call it like this:

Window owner = UIHelper.FindVisualParent<Window>(myControl);

answered Mar 11, 2009 at 21:28

John Myczek's user avatar

John MyczekJohn Myczek

12k4 gold badges31 silver badges44 bronze badges

1

I may be just repeating everyone else but I do have a pretty piece of code that extends the DependencyObject class with a method FindChild() that will get you the child by type and name. Just include and use.

public static class UIChildFinder
{
    public static DependencyObject FindChild(this DependencyObject reference, string childName, Type childType)
    {
        DependencyObject foundChild = null;
        if (reference != null)
        {
            int childrenCount = VisualTreeHelper.GetChildrenCount(reference);
            for (int i = 0; i < childrenCount; i++)
            {
                var child = VisualTreeHelper.GetChild(reference, i);
                // If the child is not of the request child type child
                if (child.GetType() != childType)
                {
                    // recursively drill down the tree
                    foundChild = FindChild(child, childName, childType);
                    if (foundChild != null) break;
                }
                else if (!string.IsNullOrEmpty(childName))
                {
                    var frameworkElement = child as FrameworkElement;
                    // If the child's name is set for search
                    if (frameworkElement != null && frameworkElement.Name == childName)
                    {
                        // if the child's name is of the request name
                        foundChild = child;
                        break;
                    }
                }
                else
                {
                    // child element found.
                    foundChild = child;
                    break;
                }
            }
        }
        return foundChild;
    }
}

Hope you find it useful.

google dev's user avatar

answered Oct 1, 2009 at 0:52

Tri Q Tran's user avatar

Tri Q TranTri Q Tran

5,4702 gold badges36 silver badges58 bronze badges

1

If you want to find ALL controls of a specific type, you might be interested in this snippet too

    public static IEnumerable<T> FindVisualChildren<T>(DependencyObject parent) 
        where T : DependencyObject
    {
        int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
        for (int i = 0; i < childrenCount; i++)
        {
            var child = VisualTreeHelper.GetChild(parent, i);

            var childType = child as T;
            if (childType != null)
            {
                yield return (T)child;
            }

            foreach (var other in FindVisualChildren<T>(child))
            {
                yield return other;
            }
        }
    }

answered Feb 10, 2012 at 14:23

3

This will dismiss some elements — you should extend it like this in order to support a wider array of controls. For a brief discussion, have a look here

 /// <summary>
 /// Helper methods for UI-related tasks.
 /// </summary>
 public static class UIHelper
 {
   /// <summary>
   /// Finds a parent of a given item on the visual tree.
   /// </summary>
   /// <typeparam name="T">The type of the queried item.</typeparam>
   /// <param name="child">A direct or indirect child of the
   /// queried item.</param>
   /// <returns>The first parent item that matches the submitted
   /// type parameter. If not matching item can be found, a null
   /// reference is being returned.</returns>
   public static T TryFindParent<T>(DependencyObject child)
     where T : DependencyObject
   {
     //get parent item
     DependencyObject parentObject = GetParentObject(child);

     //we've reached the end of the tree
     if (parentObject == null) return null;

     //check if the parent matches the type we're looking for
     T parent = parentObject as T;
     if (parent != null)
     {
       return parent;
     }
     else
     {
       //use recursion to proceed with next level
       return TryFindParent<T>(parentObject);
     }
   }

   /// <summary>
   /// This method is an alternative to WPF's
   /// <see cref="VisualTreeHelper.GetParent"/> method, which also
   /// supports content elements. Do note, that for content element,
   /// this method falls back to the logical tree of the element!
   /// </summary>
   /// <param name="child">The item to be processed.</param>
   /// <returns>The submitted item's parent, if available. Otherwise
   /// null.</returns>
   public static DependencyObject GetParentObject(DependencyObject child)
   {
     if (child == null) return null;
     ContentElement contentElement = child as ContentElement;

     if (contentElement != null)
     {
       DependencyObject parent = ContentOperations.GetParent(contentElement);
       if (parent != null) return parent;

       FrameworkContentElement fce = contentElement as FrameworkContentElement;
       return fce != null ? fce.Parent : null;
     }

     //if it's not a ContentElement, rely on VisualTreeHelper
     return VisualTreeHelper.GetParent(child);
   }
}

answered Jun 25, 2009 at 9:40

Philipp's user avatar

PhilippPhilipp

3012 silver badges4 bronze badges

3

I edited CrimsonX’s code as it was not working with superclass types:

public static T FindChild<T>(DependencyObject depObj, string childName)
   where T : DependencyObject
{
    // Confirm obj is valid. 
    if (depObj == null) return null;

    // success case
    if (depObj is T && ((FrameworkElement)depObj).Name == childName)
        return depObj as T;

    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
    {
        DependencyObject child = VisualTreeHelper.GetChild(depObj, i);

        //DFS
        T obj = FindChild<T>(child, childName);

        if (obj != null)
            return obj;
    }

    return null;
}

answered Jun 10, 2010 at 13:57

andresp's user avatar

andrespandresp

1,62419 silver badges31 bronze badges

3

Whilst I love recursion in general, it’s not as efficient as iteration when programming in C#, so perhaps the following solution is neater than the one suggested by John Myczek? This searches up a hierarchy from a given control to find an ancestor control of a particular type.

public static T FindVisualAncestorOfType<T>(this DependencyObject Elt)
    where T : DependencyObject
{
    for (DependencyObject parent = VisualTreeHelper.GetParent(Elt);
        parent != null; parent = VisualTreeHelper.GetParent(parent))
    {
        T result = parent as T;
        if (result != null)
            return result;
    }
    return null;
}

Call it like this to find the Window containing a control called ExampleTextBox:

Window window = ExampleTextBox.FindVisualAncestorOfType<Window>();

answered Sep 6, 2011 at 12:31

Nathan Phillips's user avatar

Nathan PhillipsNathan Phillips

11.7k1 gold badge31 silver badges22 bronze badges

0

exciton80… I was having a problem with your code not recursing through usercontrols. It was hitting the Grid root and throwing an error. I believe this fixes it for me:

public static object[] FindControls(this FrameworkElement f, Type childType, int maxDepth)
{
    return RecursiveFindControls(f, childType, 1, maxDepth);
}

private static object[] RecursiveFindControls(object o, Type childType, int depth, int maxDepth = 0)
{
    List<object> list = new List<object>();
    var attrs = o.GetType().GetCustomAttributes(typeof(ContentPropertyAttribute), true);
    if (attrs != null && attrs.Length > 0)
    {
        string childrenProperty = (attrs[0] as ContentPropertyAttribute).Name;
        if (String.Equals(childrenProperty, "Content") || String.Equals(childrenProperty, "Children"))
        {
            var collection = o.GetType().GetProperty(childrenProperty).GetValue(o, null);
            if (collection is System.Windows.Controls.UIElementCollection) // snelson 6/6/11
            {
                foreach (var c in (IEnumerable)collection)
                {
                    if (c.GetType().FullName == childType.FullName)
                        list.Add(c);
                    if (maxDepth == 0 || depth < maxDepth)
                        list.AddRange(RecursiveFindControls(
                            c, childType, depth + 1, maxDepth));
                }
            }
            else if (collection != null && collection.GetType().BaseType.Name == "Panel") // snelson 6/6/11; added because was skipping control (e.g., System.Windows.Controls.Grid)
            {
                if (maxDepth == 0 || depth < maxDepth)
                    list.AddRange(RecursiveFindControls(
                        collection, childType, depth + 1, maxDepth));
            }
        }
    }
    return list.ToArray();
}

answered Jun 6, 2011 at 23:26

Shawn Nelson's user avatar

Here’s my code to find controls by Type while controlling how deep we go into the hierarchy
(maxDepth == 0 means infinitely deep).

public static class FrameworkElementExtension
{
    public static object[] FindControls(
        this FrameworkElement f, Type childType, int maxDepth)
    {
        return RecursiveFindControls(f, childType, 1, maxDepth);
    }

    private static object[] RecursiveFindControls(
        object o, Type childType, int depth, int maxDepth = 0)
    {
        List<object> list = new List<object>();
        var attrs = o.GetType()
            .GetCustomAttributes(typeof(ContentPropertyAttribute), true);
        if (attrs != null && attrs.Length > 0)
        {
            string childrenProperty = (attrs[0] as ContentPropertyAttribute).Name;
            foreach (var c in (IEnumerable)o.GetType()
                .GetProperty(childrenProperty).GetValue(o, null))
            {
                if (c.GetType().FullName == childType.FullName)
                    list.Add(c);
                if (maxDepth == 0 || depth < maxDepth)
                    list.AddRange(RecursiveFindControls(
                        c, childType, depth + 1, maxDepth));
            }
        }
        return list.ToArray();
    }
}

answered Oct 20, 2010 at 10:17

exciton80's user avatar

exciton80exciton80

911 silver badge2 bronze badges

0

I have a sequence function like this (which is completely general):

    public static IEnumerable<T> SelectAllRecursively<T>(this IEnumerable<T> items, Func<T, IEnumerable<T>> func)
    {
        return (items ?? Enumerable.Empty<T>()).SelectMany(o => new[] { o }.Concat(SelectAllRecursively(func(o), func)));
    }

Getting immediate children:

    public static IEnumerable<DependencyObject> FindChildren(this DependencyObject obj)
    {
        return Enumerable.Range(0, VisualTreeHelper.GetChildrenCount(obj))
            .Select(i => VisualTreeHelper.GetChild(obj, i));
    }

Finding all children down the hiararchical tree:

    public static IEnumerable<DependencyObject> FindAllChildren(this DependencyObject obj)
    {
        return obj.FindChildren().SelectAllRecursively(o => o.FindChildren());
    }

You can call this on the Window to get all controls.

After you have the collection, you can use LINQ (i.e. OfType, Where).

answered Aug 20, 2014 at 15:45

VB Guy's user avatar

VB GuyVB Guy

991 silver badge2 bronze badges

Since the question is general enough that it might attract people looking for answers to very trivial cases: if you just want a child rather than a descendant, you can use Linq:

private void ItemsControlItem_Loaded(object sender, RoutedEventArgs e)
{
    if (SomeCondition())
    {
        var children = (sender as Panel).Children;
        var child = (from Control child in children
                 where child.Name == "NameTextBox"
                 select child).First();
        child.Focus();
    }
}

or of course the obvious for loop iterating over Children.

answered Mar 6, 2011 at 13:03

El Zorko's user avatar

El ZorkoEl Zorko

3,3092 gold badges26 silver badges34 bronze badges

These options already talk about traversing the Visual Tree in C#.
Its possible to traverse the visual tree in xaml as well using RelativeSource markup extension. msdn

find by type

Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type <TypeToFind>}}}" 

Chris's user avatar

Chris

1352 silver badges7 bronze badges

answered Apr 2, 2015 at 15:04

Neeraj's user avatar

NeerajNeeraj

6067 silver badges9 bronze badges

Here is a solution that uses a flexible predicate:

public static DependencyObject FindChild(DependencyObject parent, Func<DependencyObject, bool> predicate)
{
    if (parent == null) return null;

    int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
    for (int i = 0; i < childrenCount; i++)
    {
        var child = VisualTreeHelper.GetChild(parent, i);

        if (predicate(child))
        {
            return child;
        }
        else
        {
            var foundChild = FindChild(child, predicate);
            if (foundChild != null)
                return foundChild;
        }
    }

    return null;
}

You can for example call it like this:

var child = FindChild(parent, child =>
{
    var textBlock = child as TextBlock;
    if (textBlock != null && textBlock.Name == "MyTextBlock")
        return true;
    else
        return false;
}) as TextBlock;

answered Sep 9, 2015 at 15:54

Tim Pohlmann's user avatar

Tim PohlmannTim Pohlmann

4,1023 gold badges31 silver badges59 bronze badges

To find an ancestor of a given type from code, you can use:

[CanBeNull]
public static T FindAncestor<T>(DependencyObject d) where T : DependencyObject
{
    while (true)
    {
        d = VisualTreeHelper.GetParent(d);

        if (d == null)
            return null;

        var t = d as T;

        if (t != null)
            return t;
    }
}

This implementation uses iteration instead of recursion which can be slightly faster.

If you’re using C# 7, this can be made slightly shorter:

[CanBeNull]
public static T FindAncestor<T>(DependencyObject d) where T : DependencyObject
{
    while (true)
    {
        d = VisualTreeHelper.GetParent(d);

        if (d == null)
            return null;

        if (d is T t)
            return t;
    }
}

answered Mar 7, 2017 at 12:54

Drew Noakes's user avatar

Drew NoakesDrew Noakes

298k163 gold badges677 silver badges739 bronze badges

I can’t find my control with @CrimsonX or @Drew Noakes methods, because my ControlTemplate is located in a separated XAML file.
I have found the control using the following method:

private Image backImage;
private void Diagram_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
    // here is the example of the ControlTemplate declaration
    //<ControlTemplate x:Key="DiagramControlTemplate1" TargetType="{x:Type Diagram}">
    var ctrlTemplate = (ControlTemplate)FindResource("DiagramControlTemplate1");
    // diagram is the x:Name of TemplatedControl and, "backImage" is the name of control that I want to find.
    var imageControl = ctrlTemplate.FindName("backImage", diagram);
    if (imageControl != null)
    {
        this.backImage = (Image)imageControl;
    }
}

This is working for me.

answered Mar 15, 2021 at 2:05

antonio's user avatar

antonioantonio

5137 silver badges15 bronze badges

This code just fixes @CrimsonX answer’s bug:

 public static T FindChild<T>(DependencyObject parent, string childName)
       where T : DependencyObject
    {    
      // Confirm parent and childName are valid. 
      if (parent == null) return null;

      T foundChild = null;

      int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
      for (int i = 0; i < childrenCount; i++)
      {
        var child = VisualTreeHelper.GetChild(parent, i);
        // If the child is not of the request child type child
        T childType = child as T;
        if (childType == null)
        {
          // recursively drill down the tree
          foundChild = FindChild<T>(child, childName);

          // If the child is found, break so we do not overwrite the found child. 
          if (foundChild != null) break;
        }
        else if (!string.IsNullOrEmpty(childName))
        {
          var frameworkElement = child as FrameworkElement;
          // If the child's name is set for search
          if (frameworkElement != null && frameworkElement.Name == childName)
          {
            // if the child's name is of the request name
            foundChild = (T)child;
            break;
          }

 // recursively drill down the tree
          foundChild = FindChild<T>(child, childName);

          // If the child is found, break so we do not overwrite the found child. 
          if (foundChild != null) break;


        else
        {
          // child element found.
          foundChild = (T)child;
          break;
        }
      }

      return foundChild;
    }  

You just need to continue calling the method recursively if types are matching but names don’t (this happens when you pass FrameworkElement as T). otherwise it’s gonna return null and that’s wrong.

answered Nov 21, 2017 at 21:17

Amir Oveisi's user avatar

Amir OveisiAmir Oveisi

1,6601 gold badge16 silver badges25 bronze badges

1

Here are some methods that I use frequently..

Usage:

// Starts the search from thisUiElement (might be a UserContol, Window, etc..)
var combobox = thisUiElement.ChildOfType<ComboBox>();
var employeesListBox = thisUiElement.ChildOfName("EmployeesListBox");
// Starts the search from MainWindow to find the first DataGrid
var dataGrid = WpfUtils.ChildOfType<DataGrid>();
// Starts the search from MainWindow to find the all ListViews
List<ComboBox> allListViews = WpfUtils.ChildOfType<ListView>();
// Starts the search from MainWindow to find the element of name EmployeesComboBox
var combobox = WpfUtils.ChildOfName("EmployeesComboBox");

Implementation:

/*
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;

namespace WpfUtilities;
*/

public static class WpfUtils{

    public static Window AppMainWindow =>
        Application.Current?.MainWindow;

    #region Find By Type
    
    // Start the search from MainWindow, example usage: var combobox = WpfUtils.ChildOfType<ComboBox>();
    public static T ChildOfType<T>() where T : DependencyObject =>
        ChildOfType<T>(AppMainWindow);
        
    /// This will return the first child of type T
    public static T ChildOfType<T>(this DependencyObject parent)
        where T : DependencyObject
    {
        if (parent == null) return null;
        T child = default;
        var numVisuals = VisualTreeHelper.GetChildrenCount(parent);
        for (var i = 0; i < numVisuals; i++)
        {
            var v = VisualTreeHelper.GetChild(parent, i);
            child = v as T ?? v.ChildOfType<T>();
            if (child != null)
                break;
        }

        return child;
    }
    
    // Start the search from MainWindow, example usage: List<ComboBox> comboboxes = WpfUtils.ChildOfType<ComboBox>();
    public static IEnumerable<T> ChildrenOfType<T>() where T : DependencyObject =>
        ChildrenOfType<T>(AppMainWindow);
    
    /// This will not break the search when finding the first kid of type T, but it will keep searching to return all kids of type T
    public static IEnumerable<T> ChildrenOfType<T>(
        this DependencyObject parent) where T : DependencyObject
    {
        if (parent == null) yield break;
        var numVisuals = VisualTreeHelper.GetChildrenCount(parent);
        for (var i = 0; i < numVisuals; i++)
        {
            var child = VisualTreeHelper.GetChild(parent, i);
            if (child is T dependencyObject)
                yield return dependencyObject;

            foreach (var childOfChild in child.ChildrenOfType<T>())
                yield return childOfChild;
        }
    }
    
    #endregion  

    #region Find By Name
    
    /// If parent is null, the search will start from MainWindow, example usage: var combobox = WpfUtils.ChildOfName("EmployeesCombobox");
    public static FrameworkElement ChildOfName(string childName,
        DependencyObject parent = null)
    {
        parent ??= AppMainWindow;
        object child = null;
        var numVisuals = VisualTreeHelper.GetChildrenCount(parent);
        for (var i = 0; i < numVisuals; i++)
        {
            var v = VisualTreeHelper.GetChild(parent, i);
            child = v is FrameworkElement f && f.Name == childName
                ? f
                : ChildOfName(childName, v);

            if (child != null)
                break;
        }

        return child as FrameworkElement;
    }
    
    #endregion
    
    #region
    
    // Yet another useful method, if you are writing code in a .xaml.cs file and you want to get the parent of a type.. example usage: this.ParentOfType<Grid>(); this.ParentOfType<UserControl>(); this.ParentOfType<Window>(); 
    public static T ParentOfType<T>(this DependencyObject child) where T : DependencyObject
    {
        var parentDepObj = child;
        do
        {
            parentDepObj = VisualTreeHelper.GetParent(parentDepObj);
            if (parentDepObj is T parent) return parent;
        } while (parentDepObj != null);

        return null;
    }
    
    #endregion
}

answered Aug 25, 2022 at 5:06

Muhammad Sulaiman's user avatar

I was able to find objects by name using below code.

stkMultiChildControl = stkMulti.FindChild<StackPanel>("stkMultiControl_" + couter.ToString());

answered Dec 26, 2020 at 20:56

Hardik Shah's user avatar

Hardik ShahHardik Shah

1661 silver badge10 bronze badges

Try this

<TextBlock x:Name="txtblock" FontSize="24" >Hai Welcom to this page
</TextBlock>

Code Behind

var txtblock = sender as Textblock;
txtblock.Foreground = "Red"

dhh's user avatar

dhh

4,2648 gold badges42 silver badges59 bronze badges

answered Mar 23, 2015 at 5:57

Jayasri's user avatar

JayasriJayasri

2371 silver badge11 bronze badges

1

Permalink

Cannot retrieve contributors at this time

title ms.date dev_langs helpviewer_keywords ms.assetid description

How to: Find an Element by Its Name

03/30/2017

csharp

vb

elements [WPF], finding by name

cfa7cf35-8aa2-4060-9454-872ed4af3f0e

Learn how to use the FindName method to find an element by its Name value, with examples and links.

This example describes how to use the xref:System.Windows.FrameworkElement.FindName%2A method to find an element by its xref:System.Windows.FrameworkElement.Name%2A value.

Example

In this example, the method to find a particular element by its name is written as the event handler of a button. stackPanel is the xref:System.Windows.FrameworkElement.Name%2A of the root xref:System.Windows.FrameworkElement being searched, and the example method then visually indicates the found element by casting it as xref:System.Windows.Controls.TextBlock and changing one of the xref:System.Windows.Controls.TextBlock visible UI properties.

[!code-csharpFEFindName#Find]
[!code-vbFEFindName#Find]

How can I loop through the controls collection of a WPF panel and find a control by name?  The StackPanel1.Children(0).Name property does not exist.

I looking for a method equivelent to this WinForm code…

Friend
Function DBX_FindControlByName(ByRef
objContainer
As
Object, _

ByVal strControlName
As
String, _

ByRef objFoundControl
As Control)
As
Boolean

Dim objControl
As Control =
Nothing

If
Not IsNothing(objFoundControl)
Then
Return
True

Try

‘objContainer must be a controls collection like Me.Controls

For
Each objControl
In
CType(objContainer, Control.ControlCollection)

If objControl.Name.ToUpper = strControlName.ToUpper
Then

objFoundControl = objControl

Exit
For

Else

If objControl.HasChildren
Then

‘This control has children so it must be a container

DBX_FindControlByName(objControl.Controls, strControlName, objFoundControl)

End
If

End
If

Next

Return
True

Catch ex
As Exception

strErrMsg =

«DBX_FindControlByName.» & objControl.Name &
«: « & ex.Message

End
Try

End
Function

Thanks.

Mike

Практическое руководство. Поиск элемента по его имени

В этом примере описывается использование FindName способ поиска элемента по его Name значение.

Пример

В этом примере метод для поиска определенного элемента по его имени записывается как обработчик событий кнопки. stackPanel — Name корневого FrameworkElement искомых, и в примере метод затем визуально указывает найденный элемент, приводя его TextBlock и изменение одного из TextBlock видимым UI свойства.

void Find(object sender, RoutedEventArgs e)
{
    object wantedNode = stackPanel.FindName("dog");
    if (wantedNode is TextBlock)
    {
        // Following executed if Text element was found.
        TextBlock wantedChild = wantedNode as TextBlock;
        wantedChild.Foreground = Brushes.Blue;
    }
}

Практическое руководство. Нахождение элемента по его имени

В этом примере описывается, как использовать метод FindName для поиска элемента по его значению Name.

Например, .

В этом примере метод для поиска определенного элемента по его имени написан в качестве обработчика событий кнопки. stackPanel — это Name искомого корневого элемента FrameworkElement. Затем пример метода визуально указывает найденный элемент путем приведения его в качестве TextBlock и изменения одного из видимых свойств пользовательского интерфейса TextBlock.

Поиск — один из самых важных алгоритмов программы, без которого на сегодняшний день не обходиться не одна информационная система, особенно работающая с большими объёмами данных.

В этой статье я бы хотел рассказать и показать как можно реализовать алгоритмы поиска и фильтрации в приложении написанном на WPF C#.

Что такое WPF?

Windows Presentation Foundation — один из компонентов ядра .NET Framework, который позволяет разработчикам создавать богатые, различные Windows приложения.

Создаём интерфейс для алгоритма поиска и фильтрации.

Самое первое что нужно сделать, это запустить Microsoft Visual Studio. А далее создать проект выбрав пункт «Приложение WPF» — Visual C#;

Создание нового проекта WPF - Visual C#

Следующим шагом настроим минимальные значения высоты и ширины окна, а также зададим значения по умолчанию.

Настройка максимального значения высоты и ширины программы, а также значения по умолчанию.

Реализовываем следующий интерфейс используя такие элементы как: Label, ComboBox, TextBox, ListView, Button. Как пользоваться ListView можно прочитать в этой статье.

Интерфейс программы для реализации алгоритма поиска.

Далее, присвоим атрибут DisplayMemberBinding для тегов GridViewColumn, дав наименования в соответствии с рисунком ниже.

Атрибут DisplayMemberBinding для тегов GridViewColumn

Для элемента ComboBox зададим атрибут x:Name=»genderFilter», а для TextBox атрибут x:Name=»nameFilter», для ListView – x:Name=»userList». Так же для элемента Button создадим обработчик события на активность Click.

Обработчик события на активность Click

XAML — разметка, полный код:

Пишем алгоритм поиска и фильтрации.

В первую очередь создадим класс объектов, хранящий в себе такие переменные как name, dataOfBirth, age, gender и реализуем функцию, отвечающую за заполнение этих данных:

Сразу же создадим массив этого класса, предполагая что у нас будет несколько значений.

Далее, необходимо создать функцию LoadUser, принимающую в качестве аргумента массив класса User и вызвать её после инициализации компонентов, отправив созданный массив класса user.

Думаю не сложно догадаться что эта функция будет выводить на экран все элементы массива, который мы передадим в эту функцию.

Вызовем эту функцию в после инициализации компонентов формы, чтобы сразу же отобразить имеющиеся данные. Стоп! А какие данные мы собрались отображать? Которых нет?

Добавим эти самые данные.

Перед выполнением функции пропишем добавление данных:

Запустив программу, можно увидеть что все данные благополучно вывелись на экран программы:

Результат выполнения программы реализации алгоритма поиска

Чтож, добавим в элемент ComboBox, два TextBlock’a, задав значения Мужской и Женский на XAML-разметке.

Два TextBlock в элементе ComboBox

Следующим шагом реализовываем функцию фильтрации по признаку пола: для этого необходимо создать новый массив класса User. А далее в зависимости от выбранного значения произвести поиск в массиве с определённым условием:

Функция работает следующим образом: если у нас выбран мужской пол, то из всего массива класса будут отобраны только те элементы, которые в качестве значения gender принимают «М». Если же пол женский — соответственно будут выбраны только записи с женским полом. Если же не выбрано ни чего, то будут отображены все записи.

После сортировки по половому фильтру необходимо добавить алгоритм кода, позволяющий производить точное совпадение, со строкой находящейся в TextBox:

Contains — этот метод позволяет производить совпадение в записи числа, с каким-то конкретным значением.

Если запустить программу то, можно заметить, что фильтр по половому признаку работает. Точно также как и поиск по совпадениям.

Search in WPF DataGrid (SfDataGrid)

WPF DataGrid control allows you to search the data displayed in the SfDataGrid. You can search the data by using SearchHelper.Search method.

WPF DataGrid with Search Panel

Filtering

You can enable filter based on search by setting SearchHelper.AllowFiltering property to true.

Enabling Filter based on Search in WPF DataGrid

You can search the data with the case-sensitivity by setting SearchHelper.AllowCaseSensitiveSearch property.

Changing Search Highlight Background

In WPF DataGrid (SfDatagrid), you can change the search text highlighting color by setting SearchHelper.SearchBrush property.

Changing Search Text Highlighting Color in WPF DataGrid

Changing foreground for search highlight

In WPF DataGrid (SfDatagrid), you can change the foreground color for search text by setting the SearchHelper.SearchForegroundBrush property.

Changing Fore Color of Search Text in WPF DataGrid

Navigating cells based on search text

You can navigate to the cells contains the SearchText using SearchHelper.FindNext and SearchHelper.FindPrevious methods.

You can highlight the currently navigated search text using SearchHelper.SearchHighlightBrush property.

Highlighting Navigated Search Text in WPF DataGrid

You can highlight the foreground color of current navigated search text by using the SearchHelper.SearchForegroundHighlightBrush property.

Highlighting Current Navigated Search Text Color in WPF DataGrid

Move CurrentCell when FindNext and FindPrevious

You can move the current cell along with FindNext and FindPrevious operation using MoveCurrentCell method in selection controller.

Clear Search

You can clear the search by calling the SearchHelper.ClearSearch method.

Search operation on Master-Details View

Master-details view allows you to search the data by using SearchHelper.Search method in the ViewDefinition.DataGrid.

WPF DataGrid displays Searched Data

Navigating cells based on search text in DetailsViewDataGrid

You can navigate to the cells contains the SearchText using SearchHelper.FindNext and SearchHelper.FindPrevious methods in ViewDefinition.DataGrid.

You can get the sample from here.

NOTE

It is not possible to Navigate with the two DataGrid at a time.

Search customization

WPF DataGrid (SfDataGrid) process the search operations in SearchHelper class. You can change the default search behaviors by overriding SearchHelper class and set to SfDataGrid.SearchHelper .

Search only selected columns

You can search only selected columns by overriding SearchCell method of SearchHelper . In the SearchCell method, based on MappingName you can skip the columns that you don’t want to search.

In the below code, except Quantity column other columns are gets excluded from search.

WPF DataGrid displays Search Text only in Selected Column

Select the record based on the SearchText

You can select the records which contains the search text by using GetSearchedRecord method.

Select Record based on SearchText in WPF DataGrid

Search with the GridComboBoxColumn

You can search the data in SfDataGrid with all the GridColumns which loads TextBlock as display element. To perform the search operation in the GridComboBoxColumn you need to customize the GridComboBoxColumn . As it loads the ContentControl in display mode.

Понравилась статья? Поделить с друзьями:
  • Придумай как будет меняться направление движения ребят на обратном пути составь схему обратного пути
  • Как составить смету на замену окна
  • Купидон как найти его
  • Защитник windows код ошибки 0x800704ec как исправить
  • Известна гипотенуза как найти катеты калькулятор