抓取DataGridTemplateColumn中元素的引用

时间:2011-08-11 16:15:43

标签: wpf datagridtemplatecolumn

我一直在努力解决这个问题,但似乎无法得到任何答案。我已经模拟了一个简单的XAML文件来演示这个问题(我没有提供我真正的XAML文件,因为它的内容比这个问题所需的更多)。

这是我的问题:给定以下XAML文件,如何在代码隐藏中获取驻留在DataGridTemplateColumn.CellEditingTemplate DataTemplate中的selectHeight ComboBox的引用?我需要引用,以便我可以根据selectAge ComboBox中的选择更改ComboBox的属性。

<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
    <DataGrid Name="grdPeople"
                    AutoGenerateColumns="False"  
                    AlternatingRowBackground="LightBlue" 
                    CanUserAddRows="True" CanUserDeleteRows="True" IsEnabled="True"
                    MaxHeight="400" VerticalScrollBarVisibility="Auto">

        <DataGrid.Columns>
            <!--Name Column-->
            <DataGridTemplateColumn Header="MyName" CanUserReorder="False" CanUserResize="False"  CanUserSort="False" >
                <DataGridTemplateColumn.CellTemplate >
                    <DataTemplate>
                        <Label Content="{Binding Path=Name}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
                <DataGridTemplateColumn.CellEditingTemplate >
                    <DataTemplate>
                        <TextBox Text="{Binding Path=Name}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>

            <!--Age Column-->
            <DataGridTemplateColumn Header="MyAge">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Label Content="{Binding Path=Age}"></Label>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <ComboBox Name="selectAge" ItemsSource="{Binding Path=AgeOpts}">
                            <ComboBox.ItemTemplate>
                                <DataTemplate>
                                    <Label Content="{Binding Path=Age}"></Label>
                                </DataTemplate>
                            </ComboBox.ItemTemplate>    
                        </ComboBox>
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>

            <!--Height Column-->
            <DataGridTemplateColumn Header="MyHeight">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Label Content="{Binding Path=Height}"></Label>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <ComboBox Name="selectHeight" ItemsSource="{Binding Path=HeightOpts}">
                            <ComboBox.ItemTemplate>
                                <DataTemplate>
                                    <Label Content="{Binding Path=Height}"></Label>
                                </DataTemplate>
                            </ComboBox.ItemTemplate>
                        </ComboBox>
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

我意识到我正在尝试做的事情可能不是“最佳实践”,但我正在尝试使用遗留代码中给出的内容。

我发现这个MSDN页面与我想要做的事情有关,但我无法弄清楚如何将示例翻译成我的场景:http://msdn.microsoft.com/en-us/library/system.windows.frameworktemplate.findname.aspx

任何帮助将不胜感激!谢谢!

1 个答案:

答案 0 :(得分:5)

这是我喜欢用来导航WPF的可视树和查找控件的库脚本。

您可以像这样使用它:ComboBox cbx = FindChild<ComboBox>(grdPeople, "selectHeight");

如果找不到名为null的任何ComboBox,它将返回"selectHeight",因此请务必在使用之前检查cbx == null

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
            {
                // 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;
}

public static T FindChild<T>(DependencyObject parent)
    where T : DependencyObject
{
    // Confirm parent is 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);

            // 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;
}