none
[FilpView]如何针对某个组中的某个控件进行操作 RRS feed

  • 问题

  • 假设我有一个flipview控件,有4个组。flipview代码如下:

    <FlipView 
                     ItemsSource="{Binding Source={StaticResource cvs}}">
                    <FlipView.ItemTemplate>
                        <DataTemplate>
                            <Grid>
                                <Button Click="Button_Click_1"  HorizontalAlignment="Left" VerticalAlignment="Top">button1</Button>
                                <Button HorizontalAlignment="Right" VerticalAlignment="Bottom">button2</Button>
                            </Grid>
                        </DataTemplate>
                    </FlipView.ItemTemplate>
                    <FlipView.ItemsPanel>
                        <ItemsPanelTemplate>
                            <VirtualizingStackPanel Orientation="Horizontal"/>
                        </ItemsPanelTemplate>
                    </FlipView.ItemsPanel>
                    <FlipView.ItemContainerStyle>
                        <Style TargetType="FlipViewItem">
                            <Setter Property="Background" Value="OrangeRed"/>
                            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                            <Setter Property="VerticalContentAlignment" Value="Stretch"/>
                        </Style>
                    </FlipView.ItemContainerStyle>
                </FlipView>

    现在每个flipview中都有一个button1和button2.请问我该如何在后台代码中区分各个button1呢。

    是否和属性AutomationProperties有关?如果是,又该如何使用AutomationProperties来达到我想要的效果呢?

    2012年5月23日 8:02

答案

  • 你需要等待所有FlipViewItem都Loaded了才可以通过ItemContainerGenerator找到,所以还是将代码放入 FlipView的Loaded事件中。

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

    • 已标记为答案 frglig 2012年5月24日 2:08
    2012年5月23日 10:38
    版主

全部回复

  • 还是根据我上次说的方式,通过VisualTreeHelper找,当你找到了Button类型,你可以根据这个Button的Name来判断,你可以先在 DataTemplate中设定好x:Name然后判断是否是你要的Button.

    #pragma once
    #include "pch.h"
    
    
    using namespace Windows::UI::Xaml;
    using namespace Windows::UI::Xaml::Media;
    
    template<typename T> 
    T GetVisualChild (DependencyObject ^parent)
    {
    	T child = nullptr;
    	int numVisuals = VisualTreeHelper::GetChildrenCount(parent);
    	for(int i=0;i<numVisuals;i++){
    		DependencyObject ^d = (DependencyObject^) VisualTreeHelper::GetChild(parent,i);
    		child = dynamic_cast<T>(d);
    		if(child == nullptr)
    			child = GetVisualChild<T>(d);
    		else
    			break;
    	}
    	return child;
    };


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


    2012年5月23日 9:04
    版主
  • 你好bob!

    可是如果我给button的name属性赋值,那么每个组的button1的name属性都是一样的,并不能确认这个button1是哪个组。如下代码所示:

    <FlipView  x:Name="fv"
                     ItemsSource="{Binding Source={StaticResource cvs}}">
                <FlipView.ItemTemplate>
                    <DataTemplate>
                            <GridView ItemSource="不同的数据源">
                                <GridView.ItemTemplate>
                                    <DataTemplate>
                                        <Grid>
                                            <TextBlock Text="{Binding name2}"/>
                                        </Grid>
                                    </DataTemplate>
                                </GridView.ItemTemplate>
                                <GridView.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <WrapGrid Orientation="Horizontal"/>
                                    </ItemsPanelTemplate>
                                </GridView.ItemsPanel>
                                <GridView.ItemContainerStyle>
                                    <Style TargetType="GridViewItem">
                                        <Setter Property="Width" Value="170"/>
                                        <Setter Property="Height" Value="210"/>
                                        <Setter Property="Background" Value="OrangeRed"/>
                                        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                                        <Setter Property="VerticalContentAlignment" Value="Stretch"/>
                                    </Style>
                                </GridView.ItemContainerStyle>
                            </GridView>
                    </DataTemplate>
                </FlipView.ItemTemplate>
                <FlipView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <VirtualizingStackPanel Orientation="Horizontal"/>
                    </ItemsPanelTemplate>
                </FlipView.ItemsPanel>
                <FlipView.ItemContainerStyle>
                    <Style TargetType="FlipViewItem">
                        <Setter Property="Background" Value="OrangeRed"/>
                        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                        <Setter Property="VerticalContentAlignment" Value="Stretch"/>
                    </Style>
                </FlipView.ItemContainerStyle>
            </FlipView>

    我需要给每个Gridview不同的itemsource,请问要如何实现?


    • 已编辑 frglig 2012年5月23日 9:26
    2012年5月23日 9:24
  • 你只需要在某一个特定的FlipViewItem中可视树查找即可,不需要查找所有的FlipViewItem。 你可以通过 FlipView.ItemContainerGenerator.ContainerFromItem 或者 ContainerFromIndex 方法拿到其ItemContainer , 即 FlipViewItem

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

    2012年5月23日 9:45
    版主
  • 你好Bob!

    按照你的方法使用还是遇到点问题。

    代码如下:

    BasicPage::BasicPage()
    {
    InitializeComponent();
    m_Items = ref new Platform::Collections::Vector<Platform::Object^>();
    m_Items->Append(nullptr);
    m_Items->Append(nullptr);
    m_Items->Append(nullptr);
    m_Items->Append(nullptr);
    }

    void BasicPage::OnNavigatedTo(NavigationEventArgs^ e) {

    //下面的fv为flipview控件 DefaultViewModel->Insert("Items",m_Items); int nsize = fv->Items->Size;//nsize为4 FlipViewItem^ __fv =safe_cast<FlipViewItem^>(fv->ItemContainerGenerator->ContainerFromIndex(0));

    //__fv为 nullptr DependencyObject^ __do = fv->ItemContainerGenerator->ContainerFromIndex(0);//__do为nullptr GridView^ __gv = GetVisualChild(__fv);//crash }

    请问这是怎么回事呢?

    2012年5月23日 9:59
  • 你需要等待所有FlipViewItem都Loaded了才可以通过ItemContainerGenerator找到,所以还是将代码放入 FlipView的Loaded事件中。

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

    • 已标记为答案 frglig 2012年5月24日 2:08
    2012年5月23日 10:38
    版主
  • 谢谢Bob。

    按照你说的方法可以拿到flipviewitem了,可是还有两个奇怪的问题。

    我并不能获得全部的flipviewitem。不是很好描述。

    请问能否提供一个您的邮箱,我把demo发给您,帮忙看看?

    2012年5月24日 2:12
  • 因为ItemsControl默认需要在第一次Navigate到你要显示的Item的时候才会去Generate和Load他的ItemContainer, 这点是考虑到其性能而做的虚拟化操作。所以你只有在全部显示完成所有的Item才会能够获得全部的FlipViewItem. 

    我们还有一个事件可以很好的来拿到ItemContainer改变的通知, ItemContainerGenerator.ItemsChanged event, 在这个事件中,判断ItemsChangedEventArgs中动作,来知道是否有 ItemContainer 生成。

    我的邮箱,v-bobbao (at) microsoft dot com


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

    2012年5月24日 3:28
    版主
  • 谢谢Bob,问题已经解决。

    <FlipView.ItemsPanel> <ItemsPanelTemplate> <WrapGrid Orientation="Vertical"/>//前面我是用VirtualizingStackPanel,会出现不能拿到全部;

    //改成WrapGrid之后就行了。不知道这两个虚拟化操作有什么区别。 </ItemsPanelTemplate> </FlipView.ItemsPanel>


    2012年5月24日 4:02
  • VirtualizingStackPanel 本身就是用来提供ItemContainer虚拟化的,他会只生成需要显示的Item的ItemContainer, 而其他的待要显示的时候去生成。你换了WrapGrid 他就会一次全部给你生成好。

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

    2012年5月24日 7:41
    版主