none
[关于GridView模版]如何通过ItemContainerGenerator获取ItemTemplate中的控件 RRS feed

  • 问题

  • 在使用Gridview中遇到个问题,希望哪位大侠帮忙看看。

    //GridView如下

    <GridView x:Name="GridView5"
                              IsSwipeEnabled="False"
                              Visibility="Visible"             
                              ItemsSource="{Binding Source={StaticResource cvs2}}"                      
                              ItemTemplate="{StaticResource myTemplate}"                     
                              ScrollViewer.HorizontalScrollBarVisibility="Auto"                      
                              ScrollViewer.VerticalScrollBarVisibility="Auto"                              
                              ScrollViewer.VerticalScrollMode="Enabled"
                              SelectionMode="None"
                              Loaded="GridView5_Loaded_1">
                        <GridView.ItemsPanel>
                            <ItemsPanelTemplate>
                                <VirtualizingStackPanel Orientation="Vertical"  HorizontalAlignment="Center"/>
                            </ItemsPanelTemplate>
                        </GridView.ItemsPanel>
    </GridView>
    //数据模版如下
    <DataTemplate x:Key="myTemplate">
                <Grid>
                    <Path x:Name="TextSelectionShape" Opacity="0.33" Visibility="Visible"  Fill="OrangeRed"></Path>
                    <Grid Background="Transparent">
                        <Image Source="{Binding wbmp}" Width="{Binding PageWidth}" Height="{Binding PageHeight}"/>
                    </Grid>
                </Grid>
    </DataTemplate>

    //通过遍历可视树获取子控件

    GridViewItem^ __gvi = safe_cast<GridViewItem^>(GridView5->ItemContainerGenerator->ContainerFromIndex(Index)); Path^ __Path = GetVisualChild_Path( __gvi,L"TextSelectionShape");

    //遍历可视树方法

    Windows::UI::Xaml::Shapes::Path^ GetVisualChild_Path(Windows::UI::Xaml::DependencyObject ^parent,String^ name) { Path^ child = nullptr; int numVisuals = VisualTreeHelper::GetChildrenCount(parent); for(int i=0;i<numVisuals;i++){ DependencyObject ^d = (DependencyObject^) VisualTreeHelper::GetChild(parent,i); child = dynamic_cast<Path^>(d); if(child == nullptr || child->Name!=name) child = GetVisualChild_Path(d,name); else break; } return child; }

    请问为什么我总是获取不到想要的Path控件呢?


    2012年6月11日 9:47

答案

  • 嘿嘿,本来想偷个小懒的,看来不行,我仔细看了下你的可视树遍历的代码。在找到真正想要的Path后你没有阻断循环,还在继续循环遍历,所以出来的结果永远是null。

    正确的方法应该是:

    Windows::UI::Xaml::Shapes::Path^ GetVisualChild_Path(Windows::UI::Xaml::DependencyObject ^parent,String^ name)
    {
    	Path^ child = nullptr;
    	int numVisuals = VisualTreeHelper::GetChildrenCount(parent);
    	for(int i=0;i<numVisuals;i++){
    		DependencyObject ^d = (DependencyObject^) VisualTreeHelper::GetChild(parent,i);
    		child = dynamic_cast<Path^>(d);
    		if(child == nullptr || child->Name!=name)
    		{
    			child = GetVisualChild_Path(d,name);
    			if (child != nullptr)
    				return child;
    		}
    		else
    			return child;
    	}
    	return nullptr;
    }


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年6月12日 9:24
    版主

全部回复

  • 还是可能虚拟化导致你要获得的那个 ItemContainer还没有生成,所以 这一行 GridViewItem^ __gvi = safe_cast<GridViewItem^>(GridView5->ItemContainerGenerator->ContainerFromIndex(Index)); 其实返回了一个NULL的__gvi。

    VirtualizingStackPanel 这个ItemsPanel 是支持虚拟化的,能够根据显示的需要去动态生成ItemContainer。

    你用是StackPanel试试看。


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us


    2012年6月12日 3:00
    版主
  • 谢谢Bob的回复。

    可以确定这不是虚拟化的问题:

    1.调试过程中,__gvi的值不是NULL。

    2.我是在控件完全加载完之后,响应鼠标的操作来获取Container的。

    经过调试,发现遍历可视化子树得到的子控件,都是ItemContainerStyle中的,如“<Path x:Name="SelectingGlyph" .../>”,

    而ItemTemplate中的控件并不能被遍历到。

    我的ItemContainerStyle是用默认的,可以从blend里获得。

    PS:按照您的建议把VirualizingStackPanel 换成StackPanel,结果并未有任何改变,还是无法获取到ItemTemplate中的控件。

    关于那个Flipview的虚拟化的问题,我已经知道了,所以这个问题应该另有来源吧?

    附上flipview问题的链接给需要的人参考:

    http://social.msdn.microsoft.com/Forums/zh-CN/metroappzhcn/thread/99f066da-056d-41e6-945f-201efd3137b2

    2012年6月12日 4:42
  • 嘿嘿,本来想偷个小懒的,看来不行,我仔细看了下你的可视树遍历的代码。在找到真正想要的Path后你没有阻断循环,还在继续循环遍历,所以出来的结果永远是null。

    正确的方法应该是:

    Windows::UI::Xaml::Shapes::Path^ GetVisualChild_Path(Windows::UI::Xaml::DependencyObject ^parent,String^ name)
    {
    	Path^ child = nullptr;
    	int numVisuals = VisualTreeHelper::GetChildrenCount(parent);
    	for(int i=0;i<numVisuals;i++){
    		DependencyObject ^d = (DependencyObject^) VisualTreeHelper::GetChild(parent,i);
    		child = dynamic_cast<Path^>(d);
    		if(child == nullptr || child->Name!=name)
    		{
    			child = GetVisualChild_Path(d,name);
    			if (child != nullptr)
    				return child;
    		}
    		else
    			return child;
    	}
    	return nullptr;
    }


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年6月12日 9:24
    版主
  • 非常感谢Bob!

    问题已解决。

    2012年6月14日 2:06