如何从代码后台访问数据模板中的控件?

10

我在DataTemplate中使用了一个MediaElement,但是我无法从代码后台访问它。

我会在下面发布XAML代码:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="605*"/>
        <ColumnDefinition Width="151*"/>
    </Grid.ColumnDefinitions>
    <GroupBox Header="My Videos" Height="177" VerticalAlignment="Top" Margin="5,320,5,0" Grid.ColumnSpan="2">
        <ListBox x:Name="VideoList" ItemsSource="{Binding Videos }" Width="auto" Height=" auto" Margin="0,0,0,0" Grid.ColumnSpan="2" >
            <DataTemplate x:Name="DTVideos">
                <ListBoxItem Name="lbivid1" BorderThickness="2"  Width="240" Selected="lbivid_Selected" >
                    <MediaElement Name="vidList" Height="150" Width="150" Source="{Binding SourceUri}" Position="00:00:05" LoadedBehavior="Pause" ScrubbingEnabled="True"/>
                </ListBoxItem>
            </DataTemplate>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" Margin="0,0,0,0"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ListBox>
    </GroupBox>     
    <GroupBox Header="Preview" Height="320" Width="400" VerticalAlignment="Top" DockPanel.Dock="Left">
        <MediaElement x:Name="videoPreview" HorizontalAlignment="Left" Height="300" VerticalAlignment="Top" Width="388"/>
    </GroupBox>
</Grid>

代码后台:

 private void lbivid_Selected(object sender, RoutedEventArgs e)
 {   
    imagePreview.Visibility = Visibility.Hidden;   
    string urlStr = (VidList.Source).ToString();          
    Uri temp = new Uri(UrlStr);
    videoPreview.Source = temp;                         
 }   

请问有人能告诉我如何做到吗?

(涉及IT技术)

可能是重复问题 https://dev59.com/q2sz5IYBdhLWcg3wFT4f - Omri Btian
重复的问题:从ContentPresenter的DataTemplate中访问代码后面的命名TextBox...请参考这个问题的答案。您还可以在从CodeBehind访问XAML控件模板?帖子中找到不同的答案。 - Sheridan
使用MVVM模式如何获取和设置MediaElement的Source? - JSJ
2个回答

26
你应该能够使用FrameworkTemplate.FindName方法访问控件...首先,从一个ListBoxItem中获取ContentPresenter:

ContentPresenter contentPresenter = FindVisualChild<ContentPresenter>(yourListBoxItem);

然后从ContentPresenter中获取DataTemplate

DataTemplate yourDataTemplate = contentPresenter.ContentTemplate;

然后从DataTemplate获取MediaElement:
MediaElement yourMediaElement = yourDataTemplate.FindName("vidList", contentPresenter) 
as MediaElement;
if (yourMediaElement != null)
{
    // Do something with yourMediaElement here
}

请参阅MSDN上的FrameworkTemplate.FindName方法页面以获取更多信息。

1
+1 仅适用于对此问题有意义的答案。 - Nitin
谢谢@nit...不幸的是,似乎有人对这个答案进行了恶意或报复性的投票...没有其他理由可以将其投票否决...有些人就是这么不成熟。 - Sheridan
忽略它们..你太棒了!!! - Nitin
你太好了@nit。:) 无论如何,我不介意失去这2个声望点...我有很多可以浪费的。只是可惜有人会以这种痛苦和扭曲的方式使用StackOverflow。我对那个用户的建议:成熟点! - Sheridan
4
值得指出的是,FindVisualChild<>()方法在WPF或.NET中并不是_本地_可用的。您需要手动添加它,请参考以下SO答案示例: https://dev59.com/NILba4cB1Zd3GeqPdFnr#25229554 - XtraSimplicity
显示剩余2条评论

-2

在你的事件处理程序中,有一个发送者,它是ListBoxItem,而MediaElement是ListBoxItem.Content

var mediaElement = ((ListBoxItem)sender).Content as MediaElement;
if (mediaElement != null) ...

我认为你是错误的。你可以使用 FrameworkTemplate.FindName 方法。 - Sheridan
好的,你不能通过变量名像vidList.DoSomething()这样做。而且要使用你的解决方案,你需要以某种方式获取到FrameworkTemplate。我提供了一个简单的可行解决方案。 - Pavel Tupitsyn
如果您编辑答案并提供更准确的内容,我很乐意取消对您的负评。您的“您无法通过名称执行此操作”的说法是不正确的。 - Sheridan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接