Practice Account
Practice Account

Reputation: 11

How do I access my ComboBoxes inside of a GridViewColumn HeaderTemplate?

I found a way to template the embedding of controls within the column headings of a GridView. However I do not know how to find the controls using my code behind to fill them up with items. I have figured out how to respond to an event raised from the embedded control and determine which column it was in. Otherwise I don't know how to get a reference to the embedded ComboBoxes.

Some code to give you an idea:

<Page.Resources>
    <DataTemplate x:Key="ComboHeaderTemplate">
        <DockPanel>
            <ComboBox Name="columnHeading" />
        </DockPanel>
    </DataTemplate>
</Page.Resources>

And in the code-behind:

        GridView grdView = new GridView();

        for (int column = 1; column <= context.data.GetLength(1); column++)
        {
            GridViewColumn gvc = new GridViewColumn();
            gvc.DisplayMemberBinding = new Binding(column.ToString());
            gvc.Header = column.ToString();
            gvc.Width = 120;
            gvc.HeaderTemplate = (DataTemplate)this.Resources["ComboHeaderTemplate"];
            grdView.Columns.Add(gvc);
        }

        ListView1.View = grdView;
        ListView1.ItemsSource = dt.DefaultView;

If every ComboBox had the same list of items to choose from using data binding that would be fine as long as I could select unique values for each column.

Upvotes: 0

Views: 1588

Answers (3)

misery
misery

Reputation: 1

You can try this:

 var  cbx= gvc.HeaderTemplate.LoadContent() as ComboBox;

gvc is GridViewColumn

Upvotes: 0

Practice Account
Practice Account

Reputation: 11

Here's what I ended up with.

XAML:

    <DataTemplate x:Key="ComboHeaderTemplate">
        <DockPanel>
            <ComboBox Name="columnHeading" Loaded="columnHeadingLoaded" SelectionChanged="columnHeadingSelectedChanged" Width="Auto" />
        </DockPanel>
    </DataTemplate>

Code behind:

    private void columnHeadingLoaded(object sender, RoutedEventArgs e)
    {
        ((ComboBox)sender).ItemsSource = myList;
        ((ComboBox)sender).SelectedIndex = 0;
    }

    // My columns are named "1", "2" etc
    private void columnHeadingSelectedChanged(object sender, SelectionChangedEventArgs e)
    {
        int columnIndex = int.Parse(((ComboBox)sender).DataContext.ToString()) - 1;

        if (((ComboBox)sender).SelectedIndex == 0)
        {
            this.Headings[columnIndex] = null;
        }
        else
        {
            this.Headings[columnIndex] = ((ComboBox)sender).SelectedValue.ToString();
        }
    }

Thought I should use Data Binding in the XAML but this was easier.

Upvotes: 1

GaryT
GaryT

Reputation: 135

You could use the VisualTreeHelper to retrieve the combo-box:

Create a helper method to find the combo box on the GridViewColumn:

public T FindVisualChild<T>(DependencyObject depObj) where T : DependencyObject
{
    if (depObj != null)
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
            if (child != null && child is T)
            {
                return (T)child;
            }

            T childItem = FindVisualChild<T>(child);
            if (childItem != null) return childItem;
        }
    }
    return null;
}

To get a reference to the combo-box then do something like the following:

ComboBox cb = FindVisualChild<ComboBox>(gvc);

Hopefully this is what you are looking for?

Upvotes: 1

Related Questions