This post has 13 Replies | 3 Followers

Top 10 Contributor
Male
Posts 124
Md Nazmul Ahsan Posted: 04-11-2009 1:01 PM

Hi, I have WPF window or page, where there is a textbox, button and a label/textblock. Now I need to collect those controls name at run time (guess after click the button). How can I get those names? Anyone have any idea?

In windows form we can collect using ControlsCollections, but WPF does not have any ControlsCollections class.

"Excuse if any gaffe."

Md Nazmul Ahsan
Programmer (.NET Framework)
CIS, IADCS & DIT

  • Filed under:
Top 10 Contributor
Male
Posts 124

No one have no idea !!! Last few days I work with that then I find a way to collect the controls from  WPF window or page. But still it has some problem, let see the code first.

 

 private static void GetControlsList(Visual control, int level)
        {
                              
            int ChildNumber = VisualTreeHelper.GetChildrenCount(control);

            for (int i = 0; i <= ChildNumber - 1; i++)
            {              
                Visual ChildName = (Visual)VisualTreeHelper.GetChild(control, i);

               if (ChildName is FrameworkElement)
                {
                    sbListControls.Append("<" + ChildName.ToString() + ">");
                    sbListControls.Append(Environment.NewLine);

                    string childNameProperties = (ChildName as FrameworkElement).Name.ToString();

                    if (childNameProperties != string.Empty || childNameProperties != "")
                    {
                       // sbListControls.Append(new string(' ', level * indent));

                        sbListControls.Append("<" + childNameProperties + ">");
                      //  sbListControls.Append("<" + ChildName.GetValue(FrameworkElement.+ ">");                     
                        sbListControls.Append("<" + ChildName.GetType() + ">");

                        //sbListControls.Append(ChildName.GetType());                  
                        sbListControls.Append(Environment.NewLine);
                    }

                    //Get the child under child
                    if (VisualTreeHelper.GetChildrenCount(ChildName) > 0)
                    {
                        GetControlsList(ChildName, level + 1);
                    }                   
                }

                sbListControls.Append("</" + ChildName.ToString() + ">");
                sbListControls.Append(Environment.NewLine);
            }

           // sbListControls.Append("</" + (control as FrameworkElement).Name.ToString() + ">");
        }

 

It gives me more than the controls ...... lot more. I am totally freak out. Need some help. But main problem is I am not getting the display value of the controls.

"Excuse if any gaffe."

Md Nazmul Ahsan
Programmer (.NET Framework)
CIS, IADCS & DIT

Top 10 Contributor
Male
Posts 138

I have done a simple test for you. I have added  2 buttons and 1 textblock. I can receive all controls using UIElementCollection

Window1.xaml --> Code

//<

Grid x:Name="LayoutRoot" Background="White">

 

//<TextBlock Text="This is a text block"></TextBlock>

 

//<Button x:Name="btnHello" Content="Hello" Width="100" Height="30" Margin="0,80,0,0" Click="btnHello_Click"></Button>

 

//<Button x:Name="btn2Test" Content="Test" Width="100" Height="30" Margin="0,180,0,0"></Button>

 

//</Grid>

 Window1.xaml.cs --> code

  • UIElementCollection objUIElementCollection = LayoutRoot.Children;

    foreach (UIElement obj in objUIElementCollection) {

     if (obj.GetType().ToString() == "System.Windows.Controls.Button") {

    Button b = (Button)obj; ; MessageBox.Show(b.Name); }

    if (obj.GetType().ToString() == "System.Windows.Controls.TextBlock") {

    TextBlock t = (TextBlock)obj; ; MessageBox.Show(t.Text);

     }

    }

MJ Ferdous
Project Manager, Congral LLC
Technical Author, DevMedia, Brazil

Top 10 Contributor
Male
Posts 124

Yap we can take controls using UIElementCollection ....but... problem is I need the get that all dynamically. No hard code will be done.

"Excuse if any gaffe."

Md Nazmul Ahsan
Programmer (.NET Framework)
CIS, IADCS & DIT

Top 10 Contributor
Male
Posts 138

You wrote-->

Hi, I have WPF window or page, where there is a textbox, button and a label/textblock. Now I need to collect those controls name at run time (guess after click the button).

Sorry. I didnt get your point. You said that you have window with textbox and button/label. You need to collect all controls runtime.

and foreach (UIElement obj in objUIElementCollection) {}  loop will give you all the objects one after another in runtime.

Button b = (Button)obj;

MessageBox.Show(b.Name);

when you do specific cast by checking Type. you can set or get all properties of that object.

What do you mean by hard code here. Do you wanna add textbox, button control dynamically?

Let me know if the explanation is not clear.

MJ Ferdous
Project Manager, Congral LLC
Technical Author, DevMedia, Brazil

Top 10 Contributor
Male
Posts 124

Sorry I think, I did not make it clear. I wrote ---------------->

Hi, I have WPF window or page, where there is a textbox, button and a label/textblock. Now I need to collect those controls name at run time (guess after click the button).

----------------------------------------------------------------------

Yes your sol in absolutely right when I have same thing (textbox , button and label). If  I need to take a rediobutton or a richtextbox that code will need to modify again in......

---------------------------------------------------------------------------------------------------------

if (obj.GetType().ToString() == "System.Windows.Controls.Button") {

Button b = (Button)obj; ; MessageBox.Show(b.Name); }

if (obj.GetType().ToString() == "System.Windows.Controls.TextBlock")

------------------------------------------------------------------------------------------------------------

I can take GetType() of all obj but I can not find the display value of obj.

"Excuse if any gaffe."

Md Nazmul Ahsan
Programmer (.NET Framework)
CIS, IADCS & DIT

Top 10 Contributor
Male
Posts 138

Please let me know the type of object i.e redio button?

and name of the properties which u want to get run time.

I wanna test it for you.

Thanks

MJ Ferdous
Project Manager, Congral LLC
Technical Author, DevMedia, Brazil

Top 10 Contributor
Male
Posts 138

Sorry. I dont agree with you.

You can also get value of the object in runtime. when you have the object then you have everything of that. see the following code:

i have just tested this code to get the inner text value of RichTextBox

if (obj.GetType().ToString() == "System.Windows.Controls.RichTextBox") {

RichTextBox t = (RichTextBox)obj;

MessageBox.Show(new TextRange(t.Document.ContentStart, t.Document.ContentEnd).Text);

}

MJ Ferdous
Project Manager, Congral LLC
Technical Author, DevMedia, Brazil

Top 10 Contributor
Male
Posts 124

Sorry for late reply I was out of town for few days.Thanks for concernt about my problem. I can  not able to use LayoutRoot.Children in browser application.  Is it possible to use it in browser application?

"Excuse if any gaffe."

Md Nazmul Ahsan
Programmer (.NET Framework)
CIS, IADCS & DIT

Top 10 Contributor
Male
Posts 138

Yes it is also possible to use in Browser appliation.

Assign //x:Name="LayoutRoot"

as your grid name and use your all controls inside this. then you sould able to use it.

Thanks

MJ Ferdous
Project Manager, Congral LLC
Technical Author, DevMedia, Brazil

Top 10 Contributor
Male
Posts 124

Hi,

At last I get the solutions of this problem. Please look the reference link for details.

A Graph Tree Drawing Control for WPF

"Excuse if any gaffe."

Md Nazmul Ahsan
Programmer (.NET Framework)
CIS, IADCS & DIT

Top 10 Contributor
Male
Posts 124

I have already give a reference link to solve this problem. But I thought it is better to post some code here.

public List GetControls(object obj)
{
List<FrameworkElement> con = new List<FrameworkElement>();
return GetControls(obj,ref con);
}

private List GetControls(object obj, ref List con)
{
//Is the object is Framework Element
if (obj is FrameworkElement)
{
//Convert the object as Framework Element
FrameworkElement fe = (FrameworkElement)obj;

//Check the name
if (fe.Name.Length >0)
con.Add(fe);

// recurse through the children
IEnumerable children = LogicalTreeHelper.GetChildren(fe);
foreach (object child in children)
{
GetControls(child, ref con);
}

}

return con;
}

Thanks

"Excuse if any gaffe."

Md Nazmul Ahsan
Programmer (.NET Framework)
CIS, IADCS & DIT

Top 25 Contributor
Male
Posts 13

If you just need then controls name ....then it’s better to go with LogicalTreeHelper ....through VisualTreeHelper and LogicalTreeHelper, Simply You can traverse the whole tree and get desired control and it also help to get current Window by traversing with parent and going to root element. Anywaz nice work Nazmul Ahsan. 

binito .... Morshed Anwar       (http://morshedanwar.wordpress.com/)

Top 10 Contributor
Male
Posts 124

Hi Anwar vi, I am really sorry. I do not understand you point. Can you please describe it more?

Thanks

"Excuse if any gaffe."

Md Nazmul Ahsan
Programmer (.NET Framework)
CIS, IADCS & DIT

Page 1 of 1 (14 items) | RSS