Retreive stackpanel children from GridViewItem (UWP) - c#

I'm wondering how I can get the contents of a stackpanel which has been added to a GridViewItem (YouTube data API, the stackpanel contains a bitmap image for a thumbnail, the title of the video and a hidden TextBlock with the video ID for reference).
To clarify, I need to be able to obtain the contents of the StackPanel that is contained in the GridViewItem (such as the string of that hidden TextBox) so I can use the data to display the correct video.
Here's the code I use to create the stackpanel.
public async Task SearchByKeyword(string searchTerm)
{
GeneralFunctions gf = new GeneralFunctions();
var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
ApiKey = gf.YouTubeAPIKey,
ApplicationName = this.GetType().ToString()
});
var searchListRequest = youtubeService.Search.List("snippet");
searchListRequest.Q = searchTerm; // Replace with your search term.
searchListRequest.MaxResults = 50;
searchListRequest.SafeSearch = SearchResource.ListRequest.SafeSearchEnum.Strict;
// Call the search.list method to retrieve results matching the specified query term.
var searchListResponse = await searchListRequest.ExecuteAsync();
List<string> videos = new List<string>();
List<string> channels = new List<string>();
List<string> playlists = new List<string>();
// Add each result to the appropriate list, and then display the lists of
// matching videos, channels, and playlists.
foreach (var searchResult in searchListResponse.Items)
{
switch (searchResult.Id.Kind)
{
case "youtube#video":
// Create a new StackPanel to insert as a ListViewItem
StackPanel sPanel = new StackPanel();
sPanel.HorizontalAlignment = HorizontalAlignment.Stretch;
sPanel.VerticalAlignment = VerticalAlignment.Stretch;
sPanel.Orientation = Orientation.Vertical;
sPanel.Width = 160;
sPanel.Height = 160;
// Create new StackPanel "Child" elements with alignment and width
TextBlock tb1 = new TextBlock();
tb1.Text = searchResult.Snippet.Title;
tb1.TextWrapping = TextWrapping.WrapWholeWords;
tb1.Width = 160;
// Create new StackPanel "Child" elements with alignment and width
TextBlock tb2 = new TextBlock();
tb2.Text = searchResult.Snippet.ChannelId;
tb2.TextWrapping = TextWrapping.WrapWholeWords;
tb2.Width = 160;
// Create new StackPanel child element for a 120x120 thumbnail of the videos from the search results
Image image = new Image();
image.Source = new BitmapImage(new Uri(searchResult.Snippet.Thumbnails.Default__.Url, UriKind.Absolute));
// Add a "hidden" child element to each stackpanel to hold the video identity
TextBlock h1 = new TextBlock();
h1.Text = searchResult.Id.VideoId.ToString();
h1.Visibility = Visibility.Collapsed;
h1.TextWrapping = TextWrapping.WrapWholeWords;
sPanel.Children.Add(image);
sPanel.Children.Add(tb1);
sPanel.Children.Add(tb2);
sPanel.Children.Add(h1);
SearchResults.Items.Add(sPanel);
break;
case "youtube#channel":
//SearchResults.Items.Add(String.Format("{0} ({1})", searchResult.Snippet.Title, searchResult.Id.ChannelId));
break;
case "youtube#playlist":
//playlists.Add(String.Format("{0} ({1})", searchResult.Snippet.Title, searchResult.Id.PlaylistId));
break;
}
}
//Console.WriteLine(String.Format("Videos:\n{0}\n", string.Join("\n", videos)));
//Console.WriteLine(String.Format("Channels:\n{0}\n", string.Join("\n", channels)));
//Console.WriteLine(String.Format("Playlists:\n{0}\n", string.Join("\n", playlists)));
}
Any help is appreciated.
Thanks

I guess I should never code tired right? The answer to my own question is actually very very simple
if (SearchResults.SelectedItems.Count > 0)
{
StackPanel sp = (StackPanel)SearchResults.SelectedItem;
TextBlock tb1 = (TextBlock)sp.Children[1];
TextBlock tb2 = (TextBlock)sp.Children[2];
TextBlock hf1 = (TextBlock)sp.Children[3];
}

Related

C# Changing color on label doesnt work in my stacklayout

i am using code behind visual state managers to give selected labels a background color, but this doesnt work, any idea why?
var frameStackLayoutX = new StackLayout
{
Spacing = 5
};
var vsg = new VisualStateGroup() { Name = "CommonStates" };
var vs = new VisualState { Name = "Selected" };
vs.Setters.Add(new Setter
{
TargetName = "Selected",
Property = Label.BackgroundColorProperty,
Value = Colors.Red
});
vsg.States.Add(vs);
VisualStateManager.GetVisualStateGroups(frameStackLayoutX).Add(vsg);
var LabelName = new Label();
LabelName.Text = "Jhon Doe"
LabelName .WidthRequest = 100;
LabelName .Padding = new Thickness(10, 0, 0, 0);
frameStackLayoutX.Add(LabelName );
return frameStackLayoutX;
This is inside a grid, wherei use _lines.SelectedItem = pressedItem; to make sure that I can click on my label.

C# add an image (instead of text) to ListViewItem

I'm dynamically updating a ListView like that:
ListViewItem item = new ListViewItem();
item.Text = "Text1";
item.SubItems.Add("Text2");
item.SubItems.Add("Text3");
item.SubItems.Add("Text4");
item.Tag = i;
listView.Items.Add(item);
now I want that instead of Text4 will be a lil icon I will get dynamically from a url. I read a lot of threads and tried many things - but I can't get this to work..
You need to implement ImageList in your function.
Code :
// get picture resource
WebClient _web = new WebClient();
byte[] _data = _wb.DownloadData("http://www.myzony.com/usr/uploads/2017/03/3197402477.png");
MemoryStream _ms = new MemoryStream(_data);
// Loaded to imagelist
ImageList list = new ImageList();
list.Images.Add("pic1",Image.FromStream(_ms));
// bind listview
listView1.SmallImageList = list;
ListViewItem _item1 = new ListViewItem();
_item1.Text = "Test";
_item1.SubItems.Add("Test2");
_item1.SubItems.Add("pic1");
_item1.ImageKey = "pic1";
listView1.Items.Add(_item1);
Effect Image:

How to retrieve the name of a Panorama-Item at runtime?

I am programmatically adding items to my Panorama Control called PanoramaCC.
//function to create the panorama items in our view
private void showPanorama(string panoramaName)
{
//create the panorama item and define it
PanoramaItem genItem = new PanoramaItem();
genItem.Height = 265;
genItem.Width = 440;
genItem.Tap += new EventHandler<System.Windows.Input.GestureEventArgs>(PanoramaItem_Tap);
genItem.Name = panoramaName;
//create the stackpanel for the panoramaitem
StackPanel genStack = new StackPanel();
genStack.Orientation = System.Windows.Controls.Orientation.Horizontal;
//margin to be done
genStack.Margin = new Thickness(0, -20, 0, 20);
//load the image
Image genImg = new Image();
genImg.Height = 220;
genImg.Width = 400;
genImg.Stretch = System.Windows.Media.Stretch.Fill;
genImg.Margin = new Thickness(20, 5, 20, 5);
string path = "Assets/AppGraphics/CreditCards/" + panoramaName.ToString() + "Front.png";
Uri uriR = new Uri(path, UriKind.Relative);
BitmapImage imgSource = new BitmapImage(uriR);
genImg.Source = imgSource;
//add image into stackpanel
genStack.Children.Add(genImg);
//add stackpanel to the panoramaitem
genItem.Content = genStack;
//add the panoramaitem to the panoramaview
this.PanoramaCC.Items.Add(genItem);
}
The issue I have is that during runtime I want to retrieve the name of the panoramaItem I am currently looking at and do something with it. I've managed to retrieve the name through the tap event for navigation purposes, string name = ((PanoramaItem)sender).Name; but this is a diffrent scenario. I want to retrieve the name and then delete the item with the corresponding name. Pressing a button should delete the currently selected panoramaItem, is what I'm trying to achieve.
You can get the current PanoramaItem by using the SelectedItem property. You don't need to get the name to delete it.
PanoramaItem currentItem = myPanorama.SelectedItem as PanoramaItem;
if(currentItem != null)
{
//if you want the name for other reasons
string name = currentItem.Name;
//Items returns an ItemsCollection object
myPanorama.Items.Remove(currentItem);
}

Adding Icon to TreeViewItem

I have been asked to update a TreeVeiw in a WPF application that is built on the fly from a class object. As you will see treeveiw is not bound to anything. Below is not my code!!
<TreeView Grid.Row="0" HorizontalAlignment="Stretch" Name="tvLocations" VerticalAlignment="Stretch" SelectedItemChanged="tvLocations_SelectedItemChanged" />
private void BuildTreeVeiw(Location locationList)
{
this.Title = _selectedLoc.Name + " - Locations";
tvLocations.Items.Clear();
TreeViewItem tvitem;
tvitem = new TreeViewItem() { Header = locationList.Name, Uid = locationList.Id.ToString() };
if (locationList.Printers != null)
{
TreeViewItem tvprnitem = new TreeViewItem() { Header = "Printers" };
tvprnitem.FontWeight = FontWeights.Regular;
foreach (Printer sprinters in locationList.Printers)
{
TreeViewItem psubitem = new TreeViewItem() { Header = sprinters.Name, Uid = sprinters.Id.ToString() };
TreeViewItem psubitem1 = new TreeViewItem() { Header = String.Concat("UNC: ", sprinters.UNC) };
psubitem.Items.Add(psubitem1);
tvprnitem.Items.Add(psubitem);
}
tvitem.Items.Add(tvprnitem);
}
foreach (Location loc in locationList.Children)
{
AddChildren(loc, ref tvitem);
}
tvLocations.Items.Add(tvitem);
}
private void AddChildren(Location child, ref TreeViewItem tvi)
{
TreeViewItem tvitem;
tvitem = new TreeViewItem() { Header = child.Name, Uid = child.Id.ToString() };
if (child.Name == _currentLocation.Name)
{
tvitem.FontWeight = FontWeights.Bold;
}
if (child.Printers != null)
{
TreeViewItem tvprnitem = new TreeViewItem() { Header = "Printers" };
tvprnitem.FontWeight = FontWeights.Regular;
foreach (Printer sprinters in child.Printers)
{
TreeViewItem psubitem = new TreeViewItem() { Header = sprinters.Name, Uid = sprinters.Id.ToString() };
TreeViewItem psubitem1 = new TreeViewItem() { Header = String.Concat("UNC: ", sprinters.UNC) };
psubitem.Items.Add(psubitem1);
tvprnitem.Items.Add(psubitem);
}
tvitem.Items.Add(tvprnitem);
}
if (child.Children != null)
{
foreach (Location loc in child.Children)
{
AddChildren(loc, ref tvitem);
}
}
tvi.Items.Add(tvitem);
}
This builds the tree correctly and all I have been asked to do is add an icon to the TreeViewItem. The icon will be a different depending on whether it is a location or a printer within that location.
I cannot see how to add icons to TreeViewItems can anyone point me in the right direction?
I solved this by changing this line
tvitem = new TreeViewItem() { Header = child.Name, Uid = child.Id.ToString() };
To
tvitem = GetTreeView(child.Id.ToString(), child.Name, "location.png");
Adding this function
private TreeViewItem GetTreeView(string uid, string text, string imagePath)
{
TreeViewItem item = new TreeViewItem();
item.Uid = uid;
item.IsExpanded = false;
// create stack panel
StackPanel stack = new StackPanel();
stack.Orientation = Orientation.Horizontal;
// create Image
Image image = new Image();
image.Source = new BitmapImage
(new Uri("pack://application:,,/Images/" + imagePath));
image.Width = 16;
image.Height = 16;
// Label
Label lbl = new Label();
lbl.Content = text;
// Add into stack
stack.Children.Add(image);
stack.Children.Add(lbl);
// assign stack to header
item.Header = stack;
return item;
}
Worked perfectly.
Very nice.
I just add this inside method wich return stack panel, to make code much readable:
private StackPanel CustomizeTreeViewItem(object itemObj)
{
// Add Icon
// Create Stack Panel
StackPanel stkPanel = new StackPanel();
stkPanel.Orientation = Orientation.Horizontal;
// Create Image
Image img = new Image();
img.Source = new BitmapImage(new Uri("pack://application:,,/Resources/control.png"));
img.Width = 16;
img.Height = 16;
// Create TextBlock
TextBlock lbl = new TextBlock();
lbl.Text = itemObj.ToString();
// Add to stack
stkPanel.Children.Add(img);
stkPanel.Children.Add(lbl);
return stkPanel;
}
and in treeView Initialization
// Assign stack to header
item.Header = CustomizeTreeViewItem(itemObj);

sort stackpanel based on child elements?

Is there a way to order stackpanels based on some of its child elements?
In the code behind I add some generic things like groupbox and textblock to a stackpanel, one of the textblocks information is DateTime from my webservice, I have tryed sorting via descending order using linq but the output is still the same.
So I was wondering if its possible to sort by one of the stackpanels child elements namely the textblock1.Text that holds the DateTime attribute?
XDocument xDoc = XDocument.Load(uriGroups);
var sortedXdoc = xDoc.Descendants("Student")
.OrderByDescending(x => Convert.ToDateTime(x.Element("TimeAdded").Value));
foreach (var node in xDoc.Descendants("Student"))
{
GroupBox groupbox = new GroupBox();
groupbox.Header = String.Format(node.Element("StudentID").Value);
groupbox.Width = 100;
groupbox.Height = 100;
groupbox.Margin = new Thickness(1);
TextBlock textBlock = new TextBlock();
textBlock.Text = String.Format(node.Element("FirstName").Value + " " + (node.Element("LastName").Value));
textBlock.TextAlignment = TextAlignment.Center;
TextBlock textBlock1 = new TextBlock();
textBlock1.Text = (DateTime.Parse(node.Element("TimeAdded").Value)).ToString("d");
String.Format("{0:d/M/yyyy}", DateTime.Parse(node.Element("TimeAdded").Value));
textBlock1.TextAlignment = TextAlignment.Center;
textBlock1.VerticalAlignment = VerticalAlignment.Bottom;
StackPanel stackPanel = new StackPanel();
stackPanel.Children.Add(groupbox);
stackPanel.Children.Add(textBlock);
stackPanel.Children.Add(textBlock1);
stackPanel.Margin = new Thickness(5);
stackPanel.MouseEnter += new MouseEventHandler(stackpanel_MouseEnter);
stackPanel.MouseLeave += new MouseEventHandler(stackpanel_MouseLeave);
MainArea1.Children.Add(stackPanel);
}
}
The order of display is totally defined by the order of calls to
MainArea1.Children.Add(stackPanel);
So, try something like
foreach (var node in xDoc.Descendants("Student").OrderBy(e => ...))
{
....
}
(And you really should be using Temlates here)

Categories

Resources