I'm in the middle of creating an application that sends API calls and saves the results to a database. In order to avoid getting back to the API documentation all the time I've created a small application to remind me of the basic elements of the calls. It works by loading an xml document into memory and using a listbox to pick the appropriate call. Then its elements are displayed in textblocks (and a textbox).
The structure of the file "apicalls.xml" goes like this:
<Calls>
<Call>
<Description>blah blah</Description>
<api>POST /api/something/somethingElse/etc</api>
<Accept>application/xml</Accept>
<ContentType>application/xml</ContentType>
<Parameters>id</Parameters>
<Method>POST</Method>
<ReceiveFile>true</ReceiveFile>
<Category>aCategory</Category>
</Call> </Calls>
There are a lot of "Call" elements. So the C# code is as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Xml;
using System.Windows.Threading;
namespace ShowAPI
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public XmlDocument doc = new XmlDocument();
public MainWindow()
{
InitializeComponent();
doc.Load("apicalls.xml");
}
private void getAll(string name)
{
XmlNodeList nodeList = doc.DocumentElement.SelectNodes("Call");
int i = 0;
foreach (XmlNode node in nodeList)
{
XmlNode cat = node.SelectSingleNode("Category");
if (cat.InnerText == name)
{
ListBoxItem item = new ListBoxItem();
item.Content = (++i).ToString() + " " + node.SelectSingleNode("api").InnerText;
//item.Content = node.SelectSingleNode("api").InnerText;
item.Name = "N" + i.ToString();
list.Items.Add(item);
}
}
}
private void RadioButton_Checked(object sender, RoutedEventArgs e)
{
string name = (((RadioButton)sender).Content.ToString());
list.Items.Clear();
getAll(name);
dispatch(); // this is to display the items after the listbox has been populated
}
private void dispatch()
{
list.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);
}
private static Action EmptyDelegate = delegate () { };
private void list_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (list.Items.Count == 0)
return;
int index = list.SelectedIndex;
object sel = e.AddedItems[0];
string s = sel.ToString();
XmlNodeList nodes = doc.DocumentElement.SelectNodes("Call");
IEnumerable<RadioButton> enumerable = panel.Children.OfType<RadioButton>();
Func<RadioButton, bool> func = (x) => x.IsChecked == true;
RadioButton res = enumerable.Single<RadioButton>(func);
string find = res.Content.ToString();
List<XmlNode> nodeList = new List<XmlNode>();
foreach (XmlNode xnode in nodes)
{
XmlNode api_node = xnode.SelectSingleNode(".//api");
XmlNode cat_node = xnode.SelectSingleNode(".//Category");
string s_api = api_node.InnerText;
string s_cat = cat_node.InnerText;
if (s_cat == find)
{
nodeList.Add(xnode);
}
}
XmlNode xxx = nodeList[index];
description.Text = xxx.SelectSingleNode(".//Description").InnerText;
api.Text = xxx.SelectSingleNode(".//api").InnerText.TrimStart(new char[] { 'G', 'E', ' ', 'T', 'L', 'U', 'P', 'S', 'O', 'D' });
accept.Text = xxx.SelectSingleNode(".//Accept").InnerText;
contentType.Text = xxx.SelectSingleNode(".//ContentType").InnerText;
method.Text = xxx.SelectSingleNode(".//Method").InnerText;
expectFile.Text = xxx.SelectSingleNode(".//ReceiveFile").InnerText;
parameters.Text = xxx.SelectSingleNode(".//Parameters").InnerText;
}
}
}
and this is the ListBox implementation in xaml:
<ListBox Name ="list" HorizontalAlignment="Left" Height="396" Margin="582,52,0,0" VerticalAlignment="Top" Width="561" SelectionChanged="list_SelectionChanged">
<ListBox.Background>
<RadialGradientBrush Center="0.1,0.5" GradientOrigin="2,1" RadiusX="1" RadiusY="0.3" SpreadMethod="Reflect">
<GradientStop Color="#FFC7431C" Offset="1"/>
<GradientStop Color="#FFD31010" Offset="0.494"/>
</RadialGradientBrush>
</ListBox.Background>
</ListBox>c
So the listbox is populated normally, I can see all the items fine but when I move the mouse over them, any item beyond the 12th cannot be selected (they don't seem to be interactive - the background does not change when moving over the item).
I've tried inserting the listboxitems as objects instead of text (I've read somewhere about it) and avoided to insert identical items by adding an index number and the method name before the actual content. Nothing seems to work and I have no clue...P.S. I also used reflection to GetProperties() and compare the values of the first listboxitem with the values of the 14th listboxitem and they were identical besides the name and content. I just noticed that selecting the item with the arrow keys works fine. It's the mouse selection that won't work for any item after the 12th.
list.Items.Add(node.SelectSingleNode("api").InnerText)
? – Clemens