2014-09-22 48 views
4

XAML如何訪問XAML中ListBox的DataTemplate(但不是綁定)內部的TextBlock?

<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和其他擴展方法可以在這裏找到嘗試:

GeekChamp

Falafel Blog

但我沒有成功。我幾乎放棄了這一點。有沒有人有任何想法可以做到。謝謝。

enter image description here

正如你所看到的 - 我能順利拿到媒體隊列中,但我想顯示對「的SelectedItem」像TextBlock中扮演角色的左手側的視覺提示 - tbActive。希望這可以幫助!

+0

你需要關注GeekChamp的教程。見解決方案。 – 2014-09-23 01:16:33

+0

嗨。對不起如果我無法讓你知道我需要什麼。實際上,我已經能夠成功地獲得媒體隊列(當前在隊列中的歌曲)。但是,我想顯示一個正在播放的符號 - 在「主動歌曲」旁邊,並且「tbActive」就是這樣!我期待着能夠訪問tbActive,希望能夠改變它的'Text'屬性 - 但僅限於'SelectedItem'或'SelectedIndex'。 謝謝。 – CriticalError 2014-09-23 09:03:16

+0

是的,我的名字解決方案正是你想要的。 :) – 2014-09-23 09:19:25

回答

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); 
} 
+0

:(它沒有工作,我設置了一個斷點,'lbi'爲空,因此即使TextBlock爲空:( – CriticalError 2014-09-23 10:21:30

+0

和選定的索引號是多少?此外,如果您使用選定的項目,它在斷點處等於什麼? – 2014-09-23 10:31:03

+0

所選索引是我從'MediaPlayer.Queue.ActiveSongIndex'獲得的當前正在播放的歌曲。請看看我剛添加到我的問題中的圖片。謝謝。 – CriticalError 2014-09-23 10:46:14

0

您可以嘗試使用as操作符從ListBox的選定項目中獲取StackPanel,然後使用具有索引器的Children屬性訪問您的TextBlock。

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

你想要完成什麼工作?也許另一個綁定+可能的ValueConverter將是更好的解決方案...

+0

很確定'lsbQueue.SelectedItem'將是'歌曲',而不是控件。所以這樣做會引發一個錯誤,因爲temp會是'null'。 – 2014-09-23 01:02:42

1

以上回答將拋出一個異常 - 就像Chubosaurus軟件建議SelectedItem將是「歌」和thefore TextBlock的也將是一個null。它不會工作。

相關問題