C# 如何访问列表框内的文本块';是否在XAML中创建数据模板(但不绑定)?

C# 如何访问列表框内的文本块';是否在XAML中创建数据模板(但不绑定)?,c#,xaml,windows-phone-8,datatemplate,visualtreehelper,C#,Xaml,Windows Phone 8,Datatemplate,Visualtreehelper,XAML <ListBox x:Name="lsbQueue" Margin="0,0,0,10" Grid.RowSpan="2" Loaded="lsbQueue_Loaded" SelectionChanged="lsbQueue_SelectionChanged" ItemContainerStyle="{StaticResource ListBoxItemStyle1}" ItemsSource="{Binding}"> <ListBox.ItemTempla

XAML

<ListBox x:Name="lsbQueue" Margin="0,0,0,10" Grid.RowSpan="2" Loaded="lsbQueue_Loaded" SelectionChanged="lsbQueue_SelectionChanged" ItemContainerStyle="{StaticResource ListBoxItemStyle1}" ItemsSource="{Binding}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel x:Name="stk" Orientation="Vertical">
                <!-- This is the bugger which I need to access behind the scenes-->
                <TextBlock x:Name="tbActive" FontSize="35" FontFamily="Segoe UI Symbol" Text="" Height="115" Margin="0,0,0,-110" Tag="Active"/>
                <!-- -->
                <TextBlock Text="{Binding Path=SongName}" FontSize="35" Width="388" FontWeight="Normal" Margin="60,0,0,0"/>
                <TextBlock Width="390" FontWeight="Thin" Margin="60,-5,0,10" Opacity="0.55">
                            <Run Text="{Binding Artist}" />
                            <Run Text=", " /> <!-- space -->
                            <Run Text="{Binding Album}" />
                </TextBlock>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

上面是我的列表框,它是在以下帮助下从代码隐藏填充的:

C#

void GetQueue()
{
var songs=新列表();
对于(int i=0;i

公共类歌曲
{
公共字符串SongName{get;set;}
公共字符串相册{get;set;}
公共字符串艺术家{get;set;}
}
公共类歌曲:列表
{
公歌()
{
添加(新歌{
SongName=“”,
相册=”,
艺人=“”
});
}
}
我尝试过使用VisualTreeHelper和其他扩展方法,可在此处找到:

但我没有成功。我几乎已经放弃了。有没有人知道可以做什么。多谢各位


如您所见-我可以成功获取媒体队列,但我希望在“SelectedItem”的左侧显示一个视觉提示,就像TextBlock-tbActive中的播放字符一样。希望这有帮助

您可以尝试使用as运算符从ListBox的选定项中获取StackPanel,然后使用indexer的Children属性来获取文本块

StackPanel temp = lsbQueue.SelectedItem as StackPanel;
var textBlock = temp.Children[0] as TextBlock;
你到底想完成什么?也许另一个绑定+可能的值转换器将是更好的解决方案

因为
是您试图访问的数据模板中的第一个条目,所以请使用GeekChamp教程中提供的函数

<ListBox x:Name="lb" SelectionChanged="lb_SelectionChanged"/>


//名称空间
使用System.Windows.Media;
私有T FindFirstElementVisualTree(DependencyObject parentElement),其中T:DependencyObject
{
var count=VisualTreeHelper.GetChildrenCount(parentElement);
如果(计数=0)
返回null;
for(int i=0;i
上述答案将引发异常-就像Chubosaurus软件建议的那样,
SelectedItem
将是一首“歌曲”,而文本块也将是一个
null
。而且它不会工作。

非常确定
lsbQueue。SelectedItem
将是
song
而不是控件。这样做将抛出一个错误,因为temp将为
null
。您需要严格遵循GeekChamp的教程。见解决方案。对不起,如果我不能让你知道我需要什么。实际上,我已经成功地获得了媒体队列(队列中当前的歌曲)。但是,我想在“活动歌曲”旁边显示一个正在播放的符号,
tbActive
就是这样!我希望能够访问tbActive,希望能够更改它的
Text
属性,但仅限于
SelectedItem
SelectedIndex
。谢谢。是的,上面有我名字的解决方案完全符合您的要求。::(它不起作用。我设置了一个断点,
lbi
为空,因此即使文本块也为空:(所选索引是什么数字?如果您使用所选项目,它在断点处等于什么?所选索引是我从
MediaPlayer.Queue.ActiveSongIndex
获得的当前正在播放的歌曲。请看一看我刚才添加到问题中的图像。谢谢。好的,我们到了。索引和所选内容m必须来自您指定为ItemsSource的集合。请尝试一个常量0值,它是否至少获取列表框第一个条目的textblock?因为您必须输入的SelectedIndex必须是ItemsSource的索引值…在您的情况下,
songs.ToList()
而不是事后制作的随机列表。您的项目资源决定了列表框的输出,因此当您需要列表框中的任何内容时,必须使用相同的列表。
StackPanel temp = lsbQueue.SelectedItem as StackPanel;
var textBlock = temp.Children[0] as TextBlock;
<ListBox x:Name="lb" SelectionChanged="lb_SelectionChanged"/>
// namespaces
using System.Windows.Media;

private T FindFirstElementInVisualTree<T>(DependencyObject parentElement) where T : DependencyObject
{
    var count = VisualTreeHelper.GetChildrenCount(parentElement);
    if (count == 0)
        return null;

    for (int i = 0; i < count; i++)
    {
        var child = VisualTreeHelper.GetChild(parentElement, i);

        if (child != null && child is T)
        {
            return (T)child;
        }
        else
        {
            var result = FindFirstElementInVisualTree<T>(child);
            if (result != null)
                return result;
        }
    }
    return null;
}

private void lb_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    // get the ListBoxItem by SelectedIndex OR index number
    //ListBoxItem lbi = (ListBoxItem) this.lb.ItemContainerGenerator.ContainerFromIndex(lb.SelectedIndex);

    // get the ListBoxItem by SelectedItem or object in your ViewModel
    ListBoxItem lbi = (ListBoxItem)this.lb.ItemContainerGenerator.ContainerFromItem(lb.SelectedItem);

    // get your textbox that you want
    TextBlock tbActive= FindFirstElementInVisualTree<TextBlock>(lbi);
}