4

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 = new List<song>();

    for (int i = 0; i < MediaPlayer.Queue.Count; i++)
    {
        songs.Add(new song {
            SongName = MediaPlayer.Queue[i].Name.ToString(),
            Album = MediaPlayer.Queue[i].Album.Name.ToString(),
            Artist = MediaPlayer.Queue[i].Artist.ToString()
        });

    }
    lsbQueue.ItemsSource = songs.ToList();
    //lsbQueue.SelectedValue.ToString();
    GlobalVars._song = MediaPlayer.Queue.ActiveSongIndex;
    lsbQueue.SelectedIndex = GlobalVars._song;
    // .......
}

public class song
{
    public string SongName { get; set; }
    public string Album { get; set; }
    public string Artist { get; set; }
}

public class Song : List<song>
{
    public Song()
    {
        Add(new song { 
            SongName = "", 
            Album = "",
            Artist = ""
        });
    }
}

我尝试过使用 VisualTreeHelper 和其他扩展方法,可以在这里找到:

极客冠军

沙拉三明治博客

但我没有成功。我几乎已经放弃了这个。有没有人有任何想法可以做什么。谢谢你。

在此处输入图像描述

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

4

3 回答 3

1

由于这<TextBlock>是您尝试访问的 DataTemplate 中的第一个条目,因此请使用 GeekChamp 教程中提供的函数。

<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);
}
于 2014-09-23T01:43:33.223 回答
1

上面的答案会抛出一个异常——就像 Chubosaurus Software建议的那样,这SelectedItem将是一首“歌曲”,因此 TextBlock 也将是一个null. 而且它不会起作用。

于 2014-09-23T08:59:09.170 回答
0

您可以尝试使用 as 运算符从 ListBox 的 Selected Item 中获取 StackPanel,然后使用带有索引器的 Children 属性来访问您的 TextBlock。

StackPanel temp = lsbQueue.SelectedItem as StackPanel;
var textBlock = temp.Children[0] as TextBlock;

你到底想完成什么?也许另一个 Binding + 可能的 ValueConverter 会是更好的解决方案......

于 2014-09-22T14:32:19.800 回答