【问题标题】:How to access a Control inside the data template in C# Metro UI in the code behind如何在后面的代码中访问 C# Metro UI 中数据模板内的控件
【发布时间】:2013-02-17 20:12:34
【问题描述】:

我有一个 MediaElement,它位于 Flipview 的数据模板中,我想在后面的代码中访问名为“video”的 MediaElement,以便我可以通过按钮分配播放、暂停等属性 这是我正在尝试做的代码:

    <FlipView
    x:Name="flipView"
    AutomationProperties.AutomationId="ItemsFlipView"
    AutomationProperties.Name="Item Details"
    TabIndex="1"
    Grid.RowSpan="2"
    ItemsSource="{Binding Source={StaticResource itemsViewSource}}">

    <FlipView.ItemContainerStyle>
        <Style TargetType="FlipViewItem">
            <Setter Property="Margin" Value="0,137,0,0"/>
        </Style>
    </FlipView.ItemContainerStyle>

    <FlipView.ItemTemplate>
        <DataTemplate>
            <UserControl Loaded="StartLayoutUpdates" Unloaded="StopLayoutUpdates">
                <ScrollViewer x:Name="scrollViewer" Style="{StaticResource VerticalScrollViewerStyle}" Grid.Row="1">
                    <Grid Margin="120,0,20,20">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="400" />
                            <ColumnDefinition Width="40" />
                            <ColumnDefinition Width="360" />
                            <ColumnDefinition Width="40" />
                            <ColumnDefinition />
                        </Grid.ColumnDefinitions>
                        <Border BorderBrush="Black" BorderThickness="1" Width="350" HorizontalAlignment="Left" Grid.Row="0">
                            <MediaElement x:Name="Video" AutomationProperties.Name="Video" Source="/Assets/Big_Buck_Bunny.mp4" HorizontalAlignment="Center" VerticalAlignment="Stretch" Height="250" Width="350" AutoPlay="True" IsLooping="True" />
                        </Border>
                        <Border BorderBrush="Black" BorderThickness="1" Height="65" Width="350" HorizontalAlignment="Left" Grid.Row="1">
                            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
                                <Button x:Name="playButton" Margin="0,0" Click="playButton_Click" Style="{StaticResource PlayAppBarButtonStyle}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                                <Button x:Name="pauseButton" Margin="0,0" Click="pauseButton_Click" Style="{StaticResource PauseAppBarButtonStyle}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                            </StackPanel>
                        </Border>
                    </Grid>
                </ScrollViewer>
            </UserControl>
        </DataTemplate>
    </FlipView.ItemTemplate>
</FlipView>

我如何达到预期?

【问题讨论】:

    标签: c# xaml windows-8 windows-store-apps


    【解决方案1】:

    尝试以下方法:

        private DependencyObject FindChildControl<T>(DependencyObject control, string ctrlName)
        {
            int childNumber = VisualTreeHelper.GetChildrenCount(control);
            for (int i = 0; i < childNumber; i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(control, i);
                FrameworkElement fe = child as FrameworkElement;
                // Not a framework element or is null
                if (fe == null) return null;
    
                if (child is T && fe.Name == ctrlName)
                {
                    // Found the control so return
                    return child;
                }
                else
                {
                    // Not found it - search children
                    DependencyObject nextLevel = FindChildControl<T>(child, ctrlName);
                    if (nextLevel != null)
                        return nextLevel;
                }
            }
            return null;
        }
    

    然后从播放/暂停按钮按钮调用它:

        MediaElement media = FindChildControl<MediaElement>(this, "media") as MediaElement;
        media.Play();
    

    A related blog post on the subject

    【讨论】:

      【解决方案2】:

      大约一年前,我写了一篇关于这个主题的博客文章。或许对你有帮助:http://blog.jerrynixon.com/2012/09/how-to-access-named-control-inside-xaml.html

      要点是这样的。您必须通过可视化树进行解析以获取所有元素,然后您可以使用 LINQ 之类的东西来过滤结果并获取您的对象。

      【讨论】:

      • 尼克松感谢您的回复,我已经看过您的文章,内容非常丰富,但我有一个疑问,我在您的博客中留下了一个问题,请看一下
      【解决方案3】:

      我将 Jerry 的解决方案扩展为更灵活、性能更好的解决方案,只获取所需的控件,并且在递归调用期间不创建中间列表。

      你可以简单地使用这样来获得控制:

      var myControl = AllChildren(parent, c => c.Name == "xxx").FirstOrDefault();
      

      为此,您应该包含以下 AllChildren 函数:

       private List<Control> AllChildren(DependencyObject parent, Func<DependencyObject, bool> query,   List<Control> _List = null ) 
          {
              if (_List == null)
                   _List = new List<Control>();
      
              for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
              {
                  var _Child = VisualTreeHelper.GetChild(parent, i);
                  if (_Child is Control && query(_Child))
                  {
      
                      _List.Add(_Child as Control);
                  }
                  AllChildren(_Child, query, _List);
              }
              return _List;
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-11
        • 2010-11-18
        • 1970-01-01
        • 2015-08-30
        • 1970-01-01
        相关资源
        最近更新 更多