【问题标题】:WPF How to access control from DataTemplateWPF 如何从 DataTemplate 访问控制
【发布时间】:2011-06-02 22:25:48
【问题描述】:

我有一个包含网格的数据模板,在网格内我有一个组合框。

<DataTemplate x:Key="ShowAsExpanded">
        <Grid>                
            <ComboBox Name ="myCombo" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Top" Margin="5"
                      IsSynchronizedWithCurrentItem="True"
                      ItemsSource="{Binding}"
                      ItemTemplate="{StaticResource MyItems}">
                <ComboBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <VirtualizingStackPanel />
                    </ItemsPanelTemplate>
                </ComboBox.ItemsPanel>
            </ComboBox>

        </Grid>
    </DataTemplate>

然后我有一个通过样式引用该模板的网格。

<Grid>
    <ContentPresenter Name="_contentPresenter" Style="{DynamicResource StyleWithCollapse}" Content="{Binding}" />
</Grid>

如何通过 myCombo 的代码访问以基本设置其 DataContext?

【问题讨论】:

    标签: c# .net wpf


    【解决方案1】:

    我知道的三种方式。

    1.使用查找名称

    ComboBox myCombo =
        _contentPresenter.ContentTemplate.FindName("myCombo",
                                                   _contentPresenter) as ComboBox;
    

    2.将 Loaded 事件添加到 ComboBox 并从那里访问它

    <ComboBox Name ="myCombo" Loaded="myCombo_Loaded" ...
    
    private void myCombo_Loaded(object sender, RoutedEventArgs e)
    {
        ComboBox myCombo = sender as ComboBox; 
        // Do things..
    }
    

    3.在可视化树中找到它

    private void SomeMethod()
    {
        ComboBox myCombo = GetVisualChild<ComboBox>(_contentPresenter);
    }
    private T GetVisualChild<T>(DependencyObject parent) where T : Visual
    {
        T child = default(T);
        int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
        for (int i = 0; i < numVisuals; i++)
        {
            Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
            child = v as T;
            if (child == null)
            {
                child = GetVisualChild<T>(v);
            }
            if (child != null)
            {
                break;
            }
        }
        return child;
    }
    

    【讨论】:

    • 谢谢,非常有帮助,但 Geert van Horrik 的回答让我觉得通过后面的代码访问不是正确的方法......
    【解决方案2】:

    首先,我什至找不到资源 (ShowAsExpanded) 和 ContentPresenter 内部的用法之间的关系。但目前,我们假设 DynamicResource 应该指向 ShowAsExpanded。

    您不能也不应该通过代码访问组合框。您应该将数据上下文绑定到使用该样式的网格。如果您不想这样做,则必须在运行时查找内容并搜索子组合框。

    【讨论】:

    • 有趣。我对 wpf 还很陌生。在网格上设置datacontext,这如何传播到模板中的组合框?另外,如果我的模板中有 2 个组合框,如果每个组合具有不同的数据上下文,每个组合的数据上下文应该如何绑定?
    • 只要您没有明确设置该子项的数据上下文,数据上下文就会传播给子项。因此,如果您在 Grid 上设置数据上下文,ContentPresenter(以及下面的所有控件)将共享该数据上下文并可以绑定到它。
    • 如果我的模板中有 2 个组合框需要通过 2 个不同的集合进行绑定,该怎么做?
    • 您创建一个包含这两个集合的数据对象,然后将 datacontext 设置为该对象的一个​​实例。然后,您可以将两个组合框绑定到正确的集合。
    • 您的回答是有道理的,将ContentPresenter 绑定到不同的集合可以正常工作。但是,如果我的数据模板包含一个ListView,我有时想为其添加GroupDescriptions,该怎么办? AFAIK 这只能在代码隐藏中完成。
    【解决方案3】:
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 2010-12-12
    • 1970-01-01
    • 2016-06-26
    相关资源
    最近更新 更多