i need to extend the DropDownList For adding toolTip For DropDown Item On mouseOver.
If(Dropdown size is samller than Dropdownlist item then it will be useful for seeing the item as tool tip)
For that i came to know, We need to create ServerControl project in VS2008 but i dont know how to add a property like ItemToolTip
which need to be worked as (DataTextField, DataValueField in drop down list) in that class .
tell me any link for ServerControl project sample which resembles my requirement.
I tried using below code but dropdown property itself not working..
namespace DropDownItemToolTip
{
[DefaultProperty("Text")]
[ToolboxData("<{0}:ServerControl1 runat=server></{0}:ServerControl1>")]
public class ServerControl1 : System.Web.UI.WebControls.DropDownList
{
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(true)]
public string Text1
{
get
{
String s = (String)ViewState["Text"];
return ((s == null) ? "[" + this.ID + "]" : s);
}
set
{
ViewState["Text"] = value;
}
}
protected override void RenderContents(HtmlTextWriter output)
{
output.Write(Text1);
}
}
}
Send me any sample project link, which done like this..
Why you want to extend the Dropdownlist? Try adding a Title tag will work right?
Try this code
<select>
<option title="this is a long text">Long text</option>
</select>
It will show a this is a long text tooltip on mouseover.
Try this:
using System.Collections;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Foo
{
[ToolboxData("<{0}:DDL runat=\"server\" />")]
public class DDL : DropDownList
{
[Category("Data"), DefaultValue("")]
public string DataToolTipField
{
get { return (string)(ViewState["DataToolTipField"] ?? string.Empty); }
set { ViewState["DataToolTipField"] = value; }
}
protected override void PerformDataBinding(IEnumerable dataSource)
{
base.PerformDataBinding(dataSource);
string dataToolTipField = this.DataToolTipField;
if (!string.IsNullOrEmpty(dataToolTipField))
{
IEnumerator enumerator = dataSource.GetEnumerator();
for (int i = 0; enumerator.MoveNext(); i++)
{
this.Items[i].Attributes.Add("title", (string)DataBinder.GetPropertyValue(enumerator.Current, dataToolTipField));
}
}
}
}
}
Related
I'm working on an application in C# (MVVM) WPF developed by someone else.
In this application some grouping are made on a List of string property in a ListView, the grouping on this property seems to be working but the problem is that the groups are not sorted alphabetically by group name in the ListView.
For example :
CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(AvailablePackages);
PropertyGroupDescription groupDescription = new PropertyGroupDescription("SupportedOperatingSystems");
view.GroupDescriptions.Add(groupDescription);
view.SortDescriptions.Add(new SortDescription("SupportedOperatingSystems", ListSortDirection.Ascending));
The property "SupportedOperatingSystems" is a List of string.
The line : view.SortDescriptions.Add(new SortDescription("SupportedOperatingSystems", ListSortDirection.Ascending)); is throwing an exception :
System.InvalidOperationException: 'Failed to compare two elements in the array.'
Thanks per advance for your help :)
SortDescription only specifies information about the property by which to sort and the sort order.
Using this information, the CollectionView sorts the items by this property.
But for sorting, the type used for the sorted property must have the IComparable interface implemented.
If this interface does not exist, then the error you specified is raised.
No .Net collections, as far as I know, has an implementation of this interface.
To solve the problem, you need to reflect the elements of the original collection into an additional type for the View.
In this type, add a property to which the collection of the original element will be reflected in the converted to type with the IComparable implementation.
Not knowing the details of your implementation, I cannot give you the exact code on how to implement this.
Therefore, I show a very simplified example:
using System;
using System.Collections.Generic;
namespace SortDescriptionList
{
public class ListItem
{
public IReadOnlyList<string> Strings { get; }
public string ViewStrings => string.Join(", ", Strings);
public ListItem(params string[] strings)
=> Strings = Array.AsReadOnly(strings);
}
}
using System;
using System.Collections.Generic;
namespace SortDescriptionList
{
public class StringCollection : List<string>, IComparable, IComparable<IReadOnlyList<string>>
{
public int CompareTo(IReadOnlyList<string> other)
{
if (other == null)
return 1;
var minCount = Count;
if (minCount > other.Count)
minCount = other.Count;
if (minCount > 0)
{
for (int i = 0; i < minCount; i++)
{
var comp = string.Compare(this[i], other[i]);
if (comp != 0)
return comp;
}
}
return Count.CompareTo(other.Count);
}
public int CompareTo(object obj)
=> CompareTo(obj as IReadOnlyList<string>);
}
}
namespace SortDescriptionList
{
public class ListItemView
{
public StringCollection StringsView { get; }
public string ViewStrings => Source.ViewStrings;
public ListItem Source { get; }
public ListItemView(ListItem source)
{
Source = source;
StringsView = new StringCollection();
StringsView.AddRange(source.Strings);
}
}
}
using System.Collections.Generic;
using System.Linq;
namespace SortDescriptionList
{
public class ViewModel
{
public List<ListItem> ListItems { get; }
= new List<ListItem>()
{
new ListItem("First"),
new ListItem("Second"),
new ListItem("Third"),
new ListItem("Fourth", "Fifth")
};
public List<ListItemView> ListItemsView { get; }
public ViewModel()
{
ListItemsView = new List<ListItemView>(ListItems.Select(item => new ListItemView(item)));
}
}
}
<Window x:Class="SortDescriptionList.SortListWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SortDescriptionList"
mc:Ignorable="d"
Title="SortListWindow" Height="450" Width="800">
<FrameworkElement.DataContext>
<local:ViewModel/>
</FrameworkElement.DataContext>
<UniformGrid Columns="2">
<DataGrid x:Name="dataGrid"
ItemsSource="{Binding ListItems}"/>
<DataGrid x:Name="dataGridView"
ItemsSource="{Binding ListItemsView}"/>
</UniformGrid>
</Window>
The left column displays the DataGrid with the original elements.
And the click for sorting is available only on the "ViewStrings" column, since it is impossible to create a SortDescription for the "Strings" property with the type of a regular collection.
In the right column for the reflective collection, you can enable sorting by the "StringsView" column.
Since the type of this property is no longer a regular list, but a custom StringCollection that implements the IComparable interface and, accordingly, you can create a SortDescription for it.
Complementing answer
Here is the project as zip file
I cannot judge exactly how much this is needed in practice, but the implementation you need is quite complicated and not flexible.
You can sort the elements of the OcAvailablePackages collection by the groups specified in the SupportedPlatforms collection in its elements.
But since you need to sort not by the order of the elements of the SupportedPlatforms collection, but by the sorting order of the SupportedPlatforms elements, you also need to sort them first.
To implement such sorting, I had to come up with a rather complex type:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Test_Grouping
{
public class CompareReadOnlyList<T> : ICollection, IReadOnlyList<T>, IComparable, IComparable<IReadOnlyList<T>>
where T : IComparable, IComparable<T>
{
private readonly T[] array;
public int Count => array.Length;
public bool IsReadOnly => true;
public object SyncRoot => null;
public bool IsSynchronized => false;
public T this[int index] => array[index];
public CompareReadOnlyList(IEnumerable<T> ts)
{
array = ts.ToArray();
Array.Sort(array);
}
public CompareReadOnlyList(params T[] ts)
{
array = (T[])ts.Clone();
Array.Sort(array);
}
public int CompareTo(IReadOnlyList<T> other)
{
if (other == null)
return 1;
int minCount = Count;
if (minCount > other.Count)
{
minCount = other.Count;
}
if (minCount > 0)
{
for (int i = 0; i < minCount; i++)
{
int comp = Compare(this[i], other[i]);
if (comp != 0)
{
return comp;
}
}
}
return Count.CompareTo(other.Count);
}
public int CompareTo(object obj)
{
return CompareTo(obj as IReadOnlyList<T>);
}
public int Compare(T x, T y)
{
return x?.CompareTo(y) ?? -(y?.CompareTo(x) ?? 0);
}
public IEnumerator<T> GetEnumerator()
{
return ((IEnumerable<T>)array).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return array.GetEnumerator();
}
public void CopyTo(Array array, int index)
{
throw new NotImplementedException();
}
}
}
using Infomil.ZSYS.WSUS.Mvvm;
using System.Collections.Generic;
namespace Test_Grouping
{
public class Package : ViewModelBase
{
#region Properties
private string _name;
public string Name
{
get => _name;
set => Set(ref _name, value);
}
private CompareReadOnlyList<string> _supportedPlatforms ;
public CompareReadOnlyList<string> SupportedPlatforms
{
get => _supportedPlatforms;
set => Set(ref _supportedPlatforms, value);
}
#endregion
#region Constructors
public Package() { }
public Package(string name) => Name = name;
public Package(string name, IEnumerable<string> vs)
: this(name)
=> SupportedPlatforms = new CompareReadOnlyList<string>(vs);
public Package(string name, params string[] vs)
: this(name, (IEnumerable<string>)vs)
{ }
#endregion
#region Methods
#endregion
}
}
using Infomil.ZSYS.WSUS.Mvvm;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
namespace Test_Grouping
{
public class MainWindowVM : ViewModelBase
{
#region Properties
private ObservableCollection<Package> _ocAvailablePackages = new ObservableCollection<Package>();
public ObservableCollection<Package> OcAvailablePackages
{
get => _ocAvailablePackages;
set => Set(ref _ocAvailablePackages, value);
}
private Package _objSelectedPackage;
public Package ObjSelectedPackage
{
get => _objSelectedPackage;
set => Set(ref _objSelectedPackage, value);
}
#endregion
#region Constructors
public MainWindowVM()
{
if (DesignerProperties.GetIsInDesignMode(new DependencyObject()))
{
return;
}
//MessageBox.Show("test");
OcAvailablePackages.Add(new Package("Package 1", "Platform 2"));
OcAvailablePackages.Add(new Package("Package 2", "Platform 2", "Platform 4"));
OcAvailablePackages.Add(new Package("Package 3", "Platform 2", "Platform 1", "Platform 3"));
OcAvailablePackages.Add(new Package("Package 4", "Platform 3", "Platform 1", "Platform 4"));
OcAvailablePackages.Add(new Package("Package 5", "Platform 2", "Platform 3"));
OcAvailablePackages.Add(new Package("Package 6", "Platform 4", "Platform 1", "Platform 3"));
//Group
ListCollectionView view = (ListCollectionView)CollectionViewSource.GetDefaultView(OcAvailablePackages);
view.GroupDescriptions.Add(new PropertyGroupDescription(nameof(Package.SupportedPlatforms)));
//The next code row raises an exception (due to List<string>) :
view.SortDescriptions.Add(new SortDescription(nameof(Package.SupportedPlatforms), ListSortDirection.Ascending));
}
#endregion
#region Methods
#endregion
}
}
But I really don't like this implementation.
First, I'm not sure that it will always work correctly.
I have not been able to come up with a combination of values to support this assumption, but I think it is.
Secondly, this will not sort the items within the groups.
Since, first, the general collection is sorted, then it is grouped by explicitly specified groups in the collection of elements, these groups are virtual.
And although the ListView displays two dozen rows, in fact there were six items, so the same number remains.
I would implement through an additional type that represents a Package with an explicit breakdown into separate elements for each group:
using Infomil.ZSYS.WSUS.Mvvm;
using System.Collections.Generic;
using System.Linq;
namespace Test_Grouping
{
public class PackageRow : ViewModelBase
{
public Package Package { get; }
public string Platform => Package.SupportedPlatforms[index];
private readonly int index;
public string Name => Package.Name;
private PackageRow(Package package, string platform)
{
Package = package;
index = package.SupportedPlatforms.TakeWhile(p => p != platform).Count();
}
public static IEnumerable<PackageRow> CreatePackageRows(Package package)
=> package.SupportedPlatforms.Select(platform => new PackageRow(package, platform));
public static void AddInList(IList<PackageRow> packages, Package package)
{
foreach (var pv in CreatePackageRows(package))
{
packages.Add(pv);
}
}
public static void RemoveInList(IList<PackageRow> packages, Package package)
{
for (int i = packages.Count - 1; i >= 0; i--)
{
if (packages[i].Package == package)
{
packages.RemoveAt(i);
}
}
}
}
}
foreach (var pck in OcAvailablePackages)
{
PackageRow.AddInList(Packages, pck);
}
//Group
ListCollectionView viewGr = (ListCollectionView)CollectionViewSource.GetDefaultView(Packages);
viewGr.GroupDescriptions.Add(new PropertyGroupDescription(nameof(PackageRow.Platform)));
//The next code row raises an exception (due to List<string>) :
viewGr.SortDescriptions.Add(new SortDescription(nameof(PackageRow.Platform), ListSortDirection.Ascending));
viewGr.SortDescriptions.Add(new SortDescription(nameof(PackageRow.Name), ListSortDirection.Ascending));
}
public ObservableCollection<PackageRow> Packages { get; }
= new ObservableCollection<PackageRow>();
Archive with the changes made: Test_Grouping(Le Zvince).7z
Screenshot of the Application.
The left column is the output using the custom comparator implementation in the property type.
Right - with the division of the original elements into several, one for each group (platform). In this case, you do not need to modify the original Package type.
change your code to this:
CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(AvailablePackages.ItemsSource);
PropertyGroupDescription groupDescription = new PropertyGroupDescription("SupportedOperatingSystems");
view.GroupDescriptions.Add(groupDescription);
view.SortDescriptions.Add(new SortDescription("SupportedOperatingSystems", ListSortDirection.Ascending));
I think this is a somewhat easy answer but Im not able to understand how to do it.
I have an object (lets call it A) with a list of other objects (for example places)
So Im creating a Webapp and in that page I have a listbox of places (Im using the name of the places (string) as a unique id). The question is when I select an item from that list, how do I find that item in the list of places?
for example:
page.aspx:
<p style="margin-left: 40px">
Select place:</p>
<p style="margin-left: 40px">
<asp:ListBox ID="listplace" runat="server"></asp:ListBox>
</p>
page.aspx.cs:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
listplace.DataSource = A.listOfPlaces;
listplace.DataBind();
}
}
Hopefully this can help you:
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Windows.Forms;
namespace ListBox_42581647
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Doit();
}
private void Doit()
{
ListBox lb = new ListBox();//create a listbox
lb.Items.Add(new aPlace { placename = "TheBar", placeCoolFactor = "booze" });//add something to the listbox
lb.Items.Add(new aPlace { placename = "TheHouse", placeCoolFactor = "bowl"});//add something to the listbox
lb.Items.Add(new aPlace { placename = "ThePark", placeCoolFactor = "dogs" });//add something to the listbox
lb.SelectedItem = lb.Items[1];//lets fake a selection
var theSelectedPlace = lb.SelectedItem;//the actual item selected
var theSelectedPlaceName = ((aPlace)lb.SelectedItem).placename;//the selected item place name
var theSelectedPlaceCoolFactor = ((aPlace)lb.SelectedItem).placeCoolFactor;//the selected item place cool factor
//now I'll create your (lets call it A)
List<aPlace> parallelList = new List<aPlace>();//lets call it A
parallelList.Add((aPlace)lb.Items[0]);//This list contains the same items your ListBox contains
parallelList.Add((aPlace)lb.Items[1]);//This list contains the same items your ListBox contains
parallelList.Add((aPlace)lb.Items[2]);//This list contains the same items your ListBox contains
//find the selected by matching the selected Placename
aPlace theChosenPlace = parallelList.Where(p => p.placename == theSelectedPlaceName).FirstOrDefault();
//find the selected by matching the actual item
aPlace theChosenPlace2 = parallelList.Where(p => p == theSelectedPlace).FirstOrDefault();
}
}
public class aPlace
{
public string placename { get; set; }
public string placeCoolFactor { get; set; }
}
}
You can try:
string currPlace = listplace.SelectedItem.ToString();
string place = A.listOfPlaces.Where
(x => x.Contains(currPlace)).FirstOrDefault();
I need to populate a set of repeater drop down list items from a custom class but cannot seem to figure it out. It works perfectly when I use just a standard ListItem collection, but for some reason my custom class only returns a bunch of empty drop down lists. I'm new to repeaters and am trying to understand them the best I can, but this one kind of has me beat. Code is shown below. I have a base class that contains a child class, the child class is used to populate the drop down lists. When ListItemOptions is set to just a List<ListItem>', the actual type ofListItem', it works perfect. Why doesn't my repeater like my class?
// My base class. FYI: there are about 20 other properties in this class. I'm not just aimlessly jumping to a child class for fun!
public class ConfiguratorOption
{
private List<ListItemOptions> _listItemOptions = new List<ListItemOptions>();
public ConfiguratorOption() { }
public List<ListItemOptions> ListItemOptions { get { return _listItemOptions; } set { _listItemOptions = value; } }
public void AddListItemOption(string nodeId, string value, string displayName)
{
ListItemOptions lioNew = new ListItemOptions();
NodeID = nodeId;
Value = value;
DisplayName = displayName;
ListItemOptions.Add(lioNew);
}
}
// The child class.
public class ListItemOptions : IEnumerable
{
private string _nodeID = string.Empty;
private string _displayName = string.Empty;
private string _value = string.Empty;
public ListItemOptions() { }
public string NodeID { get { return _nodeID; } set { _nodeID = value; } }
public string Value { get { return _value; } set { _value = value; } }
public string DisplayName { get { return _displayName; } set { _displayName = value; } }
public IEnumerator GetEnumerator()
{
return (IEnumerator)this;
}
}
// The infamous repeater...
<asp:Repeater runat="server" ID="rptConfigurationOptions">
<ItemTemplate>
<div class="ConfigurationBlock">
<asp:DropDownList ID="ddnOption" runat="server" CssClass="DropDownStandard" style="width: 500px;" DataTextField="DisplayName" DataValueField="Value" AutoPostBack="true"
DataSource='<%# Eval("ListItemOptions") %>' OnSelectedIndexChanged="ddnOption_SelectedIndexChanged" ></asp:DropDownList>
</div>
</ItemTemplate>
</asp:Repeater>
// And the repeater code..
private void BindRepeater<T>(Repeater rpt, List<T> cOp)
{
rpt.Controls.Clear();
rpt.DataSource = cOp;
rpt.DataBind();
}
You can't use Eval this way. Eval will essentially evaluate the property and return a string. In your case that could render out looking like:
<asp:dropdown DataSource='List<ListItemOptions>'/>
Don't set the datasource via Eval. Handle the repeater's ItemDataBound event and set the DropDownList's datasource manually to the actual property.
Newb here,
I'm currently working on a form which has a combo box, which will show several Charlie Brown TV specials which you can click on to select and see a description of, rating, runtime, etc. I'm close but I'm not there in terms of populating the combo box and i'm hoping for some help and guidance. I have looked at several things others have done but i'm not knowledgeable enough to deduce the answers from what i've been able to see so far.
Right now i'm trying too:
1. get the listings from your load method
2. loop through them
3. Access my combo box to populate the box with the times from the listing.
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Globalization;//Used for Sting.ToUpperCase...
using System.Threading;
using System.Threading.Tasks;// Needed for Streaming...
using System.IO;// Needed for Streaming...
namespace a100___GUI___VideoStoreSelections
{
public partial class FormMovieLookUp : Form
{
private const String FILE_NAME = "txt_movieDescriptions.txt";//connect to text file in debug
private List<Listing> films { get; set; }
public FormMovieLookUp()
{
InitializeComponent();
}
private void cmbMovieListingBox_SelectedIndexChanged(object sender, EventArgs e)
{
txtTitleBox.Text = cmbMovieListingBox.SelectedItem.ToString();
}
//ToolBox -- my program specific tools
public List<Listing> LoadListings()//load movie descriptions as list
{
StreamReader fileIn = new StreamReader(FILE_NAME);
List<Listing> entries = new List<Listing>();
//loop through every line of the file
while (!fileIn.EndOfStream)
{
String line = fileIn.ReadLine();
String[] pieces = line.Split(':');
if (pieces.Length < 4) continue;//error handling - set to length of text items
Listing myListing = new Listing(pieces[0], pieces[1], pieces[2], pieces[3]);
entries.Add(myListing);
}
fileIn.Close();
return entries;
}
private void FormMovieLookUp_Load_1(object sender, EventArgs e)
{
films = LoadListings();
foreach (Listing film in films)
{
Console.WriteLine(film);
cmbMovieListingBox.Items.Add(film.GetFilmTitle());
}
}
}
}
Listing.CS
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace a100___GUI___VideoStoreSelections
{
public class Listing
{
private String filmTitle;
private String description;
private String filmRunTime;
private String filmRating;
public Listing(String filmTitle, String description, String filmRunTime, String filmRating)
{
this.filmTitle = filmTitle;
this.description = description;
this.filmRunTime = filmRunTime;
this.filmRating = filmRating;
}
public String GetFilmTitle() { return filmTitle; }
public String GetDescription() { return description; }
public String GetFilmRunTime() { return filmRunTime; }
public String GetFilmRating() { return filmRating; }
}
}
So this is what i'm trying to do to populate my combo box. Any help is thankfully received.
I would hold List<Listing> at the class level so you can access it when a user clicks on it. I would also throw this on it's own thread and not directly in the Load event. If it's a long process you will hang the ui.
private List<Listing> films { get; set; }
Load
films = LoadListings();
foreach (Listing film in films)
{
cmbMovieListingBox.Items.Add(film.GetFilmTitle());
}
When the user selects the item
Listing film = films.Where(f => f.GetFilmTitle().Equals(cmbMovieListingBox.SelectedValue)).FistOrDefault();
if (film != null)
{
//do work
}
if you are asking what i think you are asking, you need something like this in your form load:
foreach(Listing listing in LoadListings()){
cmbMovieListingBox.Items.Add(listing.GetFilmTitle());
}
Remove the {get; set;} from the list declaration. It's not needed there.
Define your class like this:
public class Listing
{
private String filmTitle {get; set;}
private String description {get; set;};
…
}
On the form load event set the ComboBox DisplayMember and ValueMember to "filmTitle"
cmbMovieListingBox.DisplayMember = "filmTitle";
cmbMovieListingBox.ValueMember = "filmTitle"
Finally, you must set the DataSource of the ComboBox to the list
cmbMovieListingBox.DataSource = films;
And there you have it. The rest of your code should function now.
There's one issue with visual controls updating (such as ComboBox etc): you'd rather prevent them from re-painting at each data change (at each item addition in your case):
cmbMovieListingBox.BeginUpdate(); // <- Stop painting
try {
// Adding new items into the cmbMovieListingBox
foreach(var item in LoadListings())
cmbMovieListingBox.Items.Add(item.GetFilmTitle());
finally {
cmbMovieListingBox.EndUpdate(); // <- Finally, repaint if required
}
A line of the code of Tsukasa doesn't work because it is written FistOrDefault() instead of FirstOrDefault()
Listing film = films.Where(f => f.GetFilmTitle().Equals(cmbMovieListingBox.SelectedValue)).**First**OrDefault();
Sorry I don't have enough point to just add a comment...
Maybe it will help somebody. But in my situation I had to use cmbMovieListingBox.Text instead of cmbMovieListingBox.SelectedValue (like #Tsukasa example):
Listing film = films.Where(f => f.GetFilmTitle().Equals(cmbMovieListingBox.Text)).FirstOrDefault();
if (film != null)
{
//do work
}
And also FirstOrDefault() instead of FistOrDefault().
Hope it helps to someone
that what i did to my Code
int Count;
foreach(String i in Languages)
{
LangComboBox.Items.Add(Languages[Count]);
Count++;
}
I am reading a setting from an XML document, converting it to a string array and then looping through each string and adding them to a DropDownList.
Everything appears to be working fine, until I actually go and look at the DropDownList itself. No matter what I do the DropDownList is empty even though when I am debugging through my code everything appears to be adding itself perfectly.
If anyone could shed a little light on why nothing is displaying despite the fact from the code's point of view it is being populated, I would appreciate it.
My code can be found below (Please note I have also tried populating it via Data Binding but I am still having the same issue.):
public class InstrumentDropDownList : DropDownList
{
public InstrumentDropDownList()
{
PopulateDropDown();
}
public void PopulateDropDown()
{
string unsplitList = Fabric.SettingsProvider.ReadSetting<string>("Setting.Location");
string[] instrumentList = unsplitList.Split(',');
DropDownList instrumentsDropDown = new DropDownList();
if (instrumentList.Length > 0)
{
foreach (string instrument in instrumentList)
{
instrumentsDropDown.Items.Add(instrument);
}
}
}
}
You're creating a new DropDownList and adding items to it. The problem is, your not doing anything with the new DropDownList you create. You are just adding the items to the wrong list.
public void PopulateDropDown()
{
string unsplitList = Fabric.SettingsProvider.ReadSetting<string>("Setting.Location");
string[] instrumentList = unsplitList.Split(',');
if (instrumentList.Length > 0)
{
foreach (string instrument in instrumentList)
{
this.Items.Add(instrument);
}
}
}
As an alternative you should be able to do this as well. You would obviously want to put in some more validation, but this is just to show that you can use the DataSource/DataBind
public void PopulateDropDown()
{
this.DataSource = fabric.SettingsProvider.ReadSetting<string>("Setting.Location").Split(',');
this.DataBind();
}
Why are you creating a new instance of the DropDownList when you are inheriting from the same class. Shouldn't you be doing something like. base.Items.Add() ??
You need to call instrumentsDropDown.DataBind after the foreach statement..
public class InstrumentDropDownList : DropDownList
{
public InstrumentDropDownList()
{
PopulateDropDown();
}
public void PopulateDropDown()
{
string unsplitList = Fabric.SettingsProvider.ReadSetting<string>("Setting.Location");
string[] instrumentList = unsplitList.Split(',');
DropDownList instrumentsDropDown = new DropDownList();
if (instrumentList.Length > 0)
{
foreach (string instrument in instrumentList)
{
instrumentsDropDown.Items.Add(instrument);
}
instrumentsDropDown.DataBind();
}
}
}