Results 1 to 15 of 15

Thread: How to loop through a set of controls on a WPF Window

  1. #1

    Thread Starter
    New Member
    Join Date
    May 2009
    Posts
    7

    How to loop through a set of controls on a WPF Window

    Hi, basically i need to loop through controls on WPF window and for perform actions with the control and gather data from it based on its type.
    I have done this before in windows forms, in WPF however i am having some problems.

    I'm afriad the actual code is at work and i won't be in till tomorrow, at which point i will update this thread with it.

    From my memory creating a loop such as this in Vb.net works fine.

    1 Code:
    1. For each c as control in Me.Controls
    2.  
    3. ...
    4.  
    5. Next

    However as WPF is different i tried using Me.content to no avail and other variations that threw an error.

    Ideas?
    Cheers
    Last edited by CJay; Sep 21st, 2009 at 11:32 AM.

  2. #2
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: How to loop through a set of controls on a WPF Window

    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  3. #3

    Thread Starter
    New Member
    Join Date
    May 2009
    Posts
    7

    Re: How to loop through a set of controls on a WPF Window

    Yeah tried that first off, before i posted here, no real help......

  4. #4
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: How to loop through a set of controls on a WPF Window

    Why is it no real help? The first link I looked at to had an example of how to do it...
    http://social.msdn.microsoft.com/For...5-9168cb4bb8dd
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  5. #5
    Lively Member
    Join Date
    Jul 2007
    Posts
    127

    Re: How to loop through a set of controls on a WPF Window

    instead of me.controls you would reference whatever the container they are in and its children. so if your using a grid,stackpanel,wrappanel or whatever your using it would just be mygrid.children. i usually use an index number when i loop, but thats prob wrong. but i do this

    Code:
    For i as int32 = 0 to mygrid.children.count -1
        If mygrid.children.item(i).gettype.fullname = gettype(Textblock).fullname then
            Dim ctrl as Textblock = ctype(mygrid.children.item(i),Textblock)
            'now you have this control. change textblock to whatever type you are looking for.
        end if
    next i
    Last edited by bflosabre91; Sep 22nd, 2009 at 10:16 AM. Reason: formatting

  6. #6

    Thread Starter
    New Member
    Join Date
    May 2009
    Posts
    7

    Re: How to loop through a set of controls on a WPF Window

    Thanks for the help everyone, I tried everything you suggested chris. I was able to count the controls. However, i was unable to directly access the object of the control, I could only return the control type. I.E textbox, stackpannel etc. Other values such as Text, tags etc where not accessable and for my desired requirements, need to be.

    I will try what you suggested saber; i tried a simular method without success, but yours is a bit different so may hopefully work.



    To go into a bit more detail about the scenario....

    my program creates controls based on data from an sql database. The way it does this is create a stackpannel, inside this stack pannel is a "title" textbox field and a "content" textbox field. There may be many of these stackpannels ( 10+) . Each stackpannel and control inside it will also contain the ID from the database in its .tag, this is the identifyer used for the resubmission of data to the database.
    So in essence create a loop such as this.

    Code:
    For each control in the content window
        If the control is a stackpanel then
            For each textbox in that stackpanel 
               connect to sql based on the textbox.tag and update the record with the textbox.text data 
           next
        end if
    next
    I will post back with any further developments , cheers everyone.


    ---------
    EDIT
    ---------

    I have For each loop version working, thanks for all the help , i will post it up later, so anyone else having this problem can see the solution.
    Last edited by CJay; Sep 22nd, 2009 at 10:34 AM.

  7. #7
    Member
    Join Date
    Sep 2002
    Location
    Massachusetts
    Posts
    48

    Re: How to loop through a set of controls on a WPF Window

    CJay, did you every solve this? I have a similar problem and I can't figure it out. I can use the code below to get to a GroupBox, but I cannot access the controls within the group box. I need to be able to read the tag on a label within the group box. Any help?

    Code:
    Private Sub SetFunLabels(ByVal TheTag As String)
    
            For i As Int32 = 0 To Grid1.Children.Count - 1
                If Grid1.Children.Item(i).GetType = GetType(GroupBox) Then
                    Dim ctrl As GroupBox = CType(Grid1.Children.Item(i), GroupBox)
                    ' I can get the group box, but i can't get the grid within the group box nor can I get the labels and textboxes within the grid
                   
                End If
            Next i

  8. #8
    Lively Member
    Join Date
    Jul 2007
    Posts
    127

    Re: How to loop through a set of controls on a WPF Window

    you just need to loop through the container in the groupbox. i would assume you have a grid or a stackpanel or something like that in the groupbox, right? then in that container is where you have the rest of your controls. so you would need to do something like this.

    Code:
            For i As Int32 = 0 To Grid1.Children.Count - 1
                If Grid1.Children.Item(i).GetType = GetType(GroupBox) Then
                    Dim ctrl As GroupBox = CType(Grid1.Children.Item(i), GroupBox)
                    If ctrl.Name = "myGroupBoxName" Then 'you might want to add this to make sure you are looping the correct groupbox in case you have more than 1
                        Dim grCtrl as Grid = CType(ctrl.content,Grid)
                          For x as Int32 = 0 To grCtrl.Children.Count - 1
                          'use the GetType function like we did above to find whatever control you want here
                          Next x
                    End If
                End If
            Next i

  9. #9
    Member
    Join Date
    Sep 2002
    Location
    Massachusetts
    Posts
    48

    Resolved Re: How to loop through a set of controls on a WPF Window

    Now it makes sense. Thanks you very much!

  10. #10
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    Re: How to loop through a set of controls on a WPF Window

    The previously suggested way of doing this is a very non-WPF way of doing things. You shouldn't be pulling values from the UI. In this instance, what we have is a collection of fields that we want to display on the screen, so first of all let's define what we mean by a field (sorry, source code supplied in C#...):
    Code:
    public class DataField : INotifyPropertyChanged
    {
        private readonly string m_databaseId;
        private readonly string m_title;
        private string m_value;
    
        public DataField(string databaseId, string title, string value)
        {
            m_databaseId = databaseId;
            m_title = title;
            m_value = value;
        }
    
        public string DatabaseId
        {
            get { return m_databaseId; }
        }
        public string Title
        {
            get { return m_title; }
        }
        public string Value
        {
            get { return m_value; }
            set
            {
                if (m_value != value)
                {
                    m_value = value;
                    OnPropertyChanged("Value");
                }
            }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            var propertyChangedHandler = PropertyChanged;
            if (propertyChangedHandler != null)
            {
                propertyChangedHandler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    Okay, having got that, let's have a collection of those as our DataContext for a window (this is just a quick fudge to get a demo working. this would obviously come from the database in the real app, and be passed in to the form):
    Code:
    public Window1 ()
    {
        // Begin new stuff
        ObservableCollection<DataField> fields = new ObservableCollection<DataField>();
    
        fields.Add(new DataField("id1", "Field 1", "Value 1"));
        fields.Add(new DataField("id2", "Field 2", "Value 2"));
        fields.Add(new DataField("id3", "Field 3", "Value 3"));
        fields.Add(new DataField("id4", "Field 4", "Value 4"));
    
        this.DataContext = fields;
        // End new stuff
    
        InitializeComponent();
    }
    Right, so now we have a collection of fields as the DataContext for our Window. We want to first of all have some way of displaying a field, so let's create a DataTemplate for that:
    Code:
    <DataTemplate DataType="{x:Type WpfSandbox:DataField}">
        <StackPanel>
            <TextBlock Text="{Binding Title}" />
            <TextBox Text="{Binding Value}" />
        </StackPanel>
    </DataTemplate>
    (Note that we're not setting the database id as the tag on the controls?)

    Then we need have the whole set of fields showing in the window. Remeber that our collection of fields is the DataContext of the window:
    Code:
    <Window x:Class="WpfSandbox.Window1"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:WpfSandbox="clr-namespace:WpfSandbox"
            Title="Window1" Height="300" Width="300">
        
        <Window.Resources>
            <DataTemplate DataType="{x:Type WpfSandbox:DataField}">
                <StackPanel>
                    <TextBlock Text="{Binding Title}" />
                    <TextBox Text="{Binding Value}" />
                </StackPanel>
            </DataTemplate>
        </Window.Resources>
    
        <ItemsControl ItemsSource="{Binding}" />
    </Window>
    When the values in the textboxes are altered, the changes will propagate back to the underlying DataField objects thanks to binding. Then the final part of the problem is to get at the DataFields at the end. Let's throw a button on the form to kick it off. Replace the ItemsControl with this:
    Code:
    <StackPanel>
        <ItemsControl ItemsSource="{Binding}" />
        <Button Click="Button_Click">Save</Button>
    </StackPanel>
    and then an event handle for the button click:
    Code:
    private void Button_Click (object sender, RoutedEventArgs e)
    {
        ObservableCollection<DataField> fields = (ObservableCollection<DataField>) this.DataContext;
    
        foreach (DataField field in fields)
        {
            MessageBox.Show(string.Format("Field {0} (Title = {1}) Value: {2}", field.DatabaseId, field.Title, field.Value));
        }
    }

  11. #11
    Member
    Join Date
    Sep 2002
    Location
    Massachusetts
    Posts
    48

    Re: How to loop through a set of controls on a WPF Window

    Thanks for the extensive reply. Since I write VB for personal use and am using the project to learn WPF I want to avoid being "un-WPF". I'll check out Data Binding and try to translate your C# code. Thanks again.

  12. #12
    Member
    Join Date
    Aug 2009
    Posts
    46

    Re: How to loop through a set of controls on a WPF Window

    rcam,

    Did you ever figure it out? I'm porting code into WPF that was done in VB and .net 2.0, and am stuck trying to do this. I have a bunch of text boxes on the screen, and while I could just do a "chkbox1.ischecked = false" type statement, I do not want to have to write like 200 lines of code each time i need to turn all boxes on or off.

    I'm going to try some of the tips here, would like to know if there was an easy way for you to figure it out, as I really do not understand this whole "walking the visual tree" speak some other sites are mentioning.

  13. #13
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    Re: How to loop through a set of controls on a WPF Window

    Due to the way WPF deals with UI, if you want to directly muck about with controls from your code then you have to walk the visual tree.

    Much better to use WPF in the way it was intended. Your "application logic" alters some objects properties, and the UI is databound to those objects, causing it to react.

  14. #14
    New Member
    Join Date
    Jan 2011
    Posts
    1

    Re: How to loop through a set of controls on a WPF Window

    I just had to solve this myself. I needed to clear the contents of all textboxes when moving from one item to another in a treeview.
    Here is what I did:
    foreach (UIElement element in grdContent.Children)
    {
    if (element.GetType).FullName== "System.Windows.Controls.TextBox")
    {
    TextBox txtClear = (TextBox)element;
    txtClear.Text = "";
    }

    }
    This is C# but I am sure you get the idea

  15. #15
    Member
    Join Date
    Sep 2002
    Location
    Massachusetts
    Posts
    48

    Re: How to loop through a set of controls on a WPF Window


    Thanks for the reply. I solved the problem by binding the controls to an observable listof (objects). and set the binding as two way. The list and controls update whenever the object element is changed. I still kind of feel like a glorified typist with WPF since I get the answers out of books or the web, without truly understanding why it works. However its getting clearer.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width