WPF: C# How to get selected value of Listbox? - c#

I am trying to fetch the selected value of the listbox. When I actually try LstGroup1.SelectedItem I get the value { BoothID = "4", BoothName = "HP" } and even if i try to get the value from LstGroup1.SelectedValue the output is same. Now I want to fetch BoothID i.e. the expected output is 4 but i am unable to get so.
My ListBox name is LstGroup1.
public List<object> BoothsInGroup1 { get; set; }
// Inside the Constructor
BoothsInGroup1 = new List<object>();
//After Fetching the value add
BoothsInGroup1.Add(new { BoothID = da["BoothID"].ToString(), BoothName = da["BoothName"].ToString() });
//Now here I get
var Booth = (LstGroup1.SelectedItem);
//Output is { BoothID = "4", BoothName = "HP" }
// Expected Output 4
Suggest me how to do that.
EDIT
public partial class VotingPanel : Window
{
public List<object> BoothsInGroup1 { get; set; }
public VotingPanel()
{
InitializeComponent();
DataContext = this;
BoothsInGroup1 = new List<object>();
//Connection is done
SqlConnection con = new SqlConnection(ConnectionString);
con.Open();
FieldNameCmd.CommandText = "SELECT * FROM Booth b, BoothGroup bg where bg.GroupID=b.GroupID;";
IDataReader da = FieldNameCmd.ExecuteReader();
while (da.Read())
{
if (Group1Name.Text == da["GroupName"].ToString())
{ // Adds value to BoothsInGroup1
BoothsInGroup1.Add(new { BoothID = da["BoothID"].ToString(), BoothName = da["BoothName"].ToString() });
}
}
}
private void BtnVote_Click(object sender, RoutedEventArgs e) // on Click wanted to find the value of Selected list box
{
if (LstGroup1.SelectedIndex >= 0 && LstGroup2.SelectedIndex >= 0)
{
var Booth = (LstGroup1.SelectedItem);
//Few things to do
}
}
}
XAML
<ListBox Grid.Row="1"
Name="LstGroup1"
ItemsSource="{Binding BoothsInGroup1}"
Margin="5,1">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding BoothID}"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
FontSize="15"
FontWeight="ExtraBold"
Margin="5,3"
Grid.Column="1" />
<TextBlock Text="{Binding BoothName}"
Grid.Column="1"
VerticalAlignment="Center"
FontWeight="ExtraBold"
FontSize="30"
Margin="15" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

since you are using anonymous type to populate the listbox, so you have left with no option then an object type to cast the SelectedItem to. other approach may include Reflection to extract the field/property values.
but if you are using C# 4 or above you may leverage dynamic
if (LstGroup1.SelectedIndex >= 0 && LstGroup2.SelectedIndex >= 0)
{
//use dynamic as type to cast your anonymous object to
dynamic Booth = LstGroup1.SelectedItem as dynamic;
//Few things to do
//you may use the above variable as
string BoothID = Booth.BoothID;
string BoothName = Booth.BoothName:
}
this may solve your current issue, but I would suggest to create a class for the same for many reasons.

I think, you should try one of the following : //EDIT : This solution only works, if Booth is a class/struct
var myBooth = LstGroup1.SelectedItem as Booth;
String id =myBooth.BoothID;
String name=myBooth.BoothName:
or use a generic list with a different type :
public List<Booth> BoothsInGroup1 { get; set; }
....
var myBooth = LstGroup1.SelectedItem;
String id =myBooth.BoothID;
Stringname=myBooth.BoothName:
And if Booth isn't a class yet, add a new class:
public class Booth
{
public int BoothID { get; set; }
public String BoothName { get; set; }
}
So u can use it in your generic list, an you can fill it after databasereading
BoothsInGroup1.Add(new Booth
{
BoothID = Convert.ToInt32(da["BoothID"]),
BoothName = da["BoothName"].ToString()
});

Have you tried :
var Booth = (LstGroup1.SelectedItem);
string ID=Booth.BoothID;
string Name=Booth.BoothName:

You can always create a class called Booth to get the data in the Object Format. From My point of view Dynamic is not the right way of doing this. Once you have the Class Booth in the Solution you can run
Booth Booth1 = LstGroup1.SelectedItem as Booth;
string BoothID1 = Booth1.BoothID;

public List<object> BoothsInGroup1 { get; set; }
BoothsInGroup1 = new List<object>();
BoothsInGroup1.Add(new { BoothID = da["BoothID"].ToString(), BoothName = da["BoothName"].ToString() });
var Booth = (LstGroup1.SelectedItem);
var output = Booth.BoothID;

For those that know the type or object that they want the code will look like this:
private void lboxAccountList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
//Class object = (Class)listName.SelectedItem;
// object.getName or object.getSomeVariable or object.callMethod(object.getName)
Account account = (Account)lboxAccountList.SelectedItem;
MessageBox.Show(""+account.AccountNo+" "+account.Balance);
}

Related

C# Xamarin Forms Populating CollectionView from ViewModel is always null

I am trying to populate a collection view from a ViewModel, however when I try to bind the data to the collection view, the ViewModel is null.
xaml.cs file
ObservableCollection<ReportsClass> newKidList = new ObservableCollection<ReportsClass>();
public ReportsViewModel viewmodel { get; set; }
public ReportsPage()
{
InitializeComponent();
viewmodel = new ReportsViewModel();
this.BindingContext = viewmodel;
PreviousDateRange.CornerRadius = 20;
NextDateRange.CornerRadius = 20;
DateTime firstDate = currentDate.StartOfWeek(DayOfWeek.Sunday);
DateTime secondDate = currentDate.AddDays(7).StartOfWeek(DayOfWeek.Saturday);
DateRange.Text = firstDate.ToString("MMMM d") + " - " + secondDate.ToString("MMMM d");
Kids.SetBinding(ItemsView.ItemsSourceProperty, nameof(viewmodel.kids));
}
Here is my view model
public class ReportsViewModel
{
public ObservableCollection<ReportsClass> kids { get; set; }
FirebaseStorageHelper firebaseStorageHelper = new FirebaseStorageHelper();
WebServiceClass webServiceClass = new WebServiceClass();
DateTime currentDate = DateTime.Now;
public ReportsViewModel()
{
GetKids();
}
public async void GetKids()
{
var parentId = await SecureStorage.GetAsync("parentid");
kids = await webServiceClass.Reports(Convert.ToInt32(parentId), currentDate.StartOfWeek(DayOfWeek.Sunday), currentDate.AddDays(7).StartOfWeek(DayOfWeek.Saturday));
}
}
And here is the method that gets the data for the view model
public async Task<ObservableCollection<ReportsClass>> Reports(int parentid, DateTime startDate, DateTime endDate)
{
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("parentid", parentid.ToString()),
new KeyValuePair<string, string>("startDate", startDate.ToString("yyyy-MM-dd H:mm:ss")),
new KeyValuePair<string, string>("endDate", endDate.ToString("yyyy-MM-dd"))
});
var response = await client.PostAsync(string.Format("https://example.com/api/index.php?action=reports"), content);
var responseString = await response.Content.ReadAsStringAsync();
ObservableCollection<ReportsClass> items = JsonConvert.DeserializeObject<ObservableCollection<ReportsClass>>(responseString);
return items;
}
What am I doing wrong? The purpose of me doing it this way is so I can update an item in the collectionview
Here is my ReportsClass
public class ReportsClass
{
public ReportsClass(string firstName)
{
first_name = firstName;
}
public string first_name { get; set; }
}
OPTION A:
Fix the syntax of Kids.SetBinding, to not get null. Refer to the CLASS ReportsViewModel, not to the INSTANCE viewmodel:
Kids.SetBinding(ItemsView.ItemsSourceProperty, nameof(ReportsViewModel.kids));
The kids still won't appear in list. To fix, kids needs OnPropertyChanged:
public ObservableCollection<ItemModel> kids {
get => _kids;
set {
_kids = value;
OnPropertyChanged();
}
}
private ObservableCollection<ItemModel> _kids;
See the other code in Option B. Adapt as desired.
When you need XAML to see a DYNAMIC change, you need OnPropertyChanged. This is an implementation of INotifyPropertyChanged. Add this call to properties (that XAML binds to) of ReportsClass:
// Inheriting from `BindableObject` is one way to obtain OnPropertyChanged method.
public class ReportsClass : Xamarin.Forms.BindableObject
{
public ReportsClass(string firstName)
{
first_name = firstName;
}
public string first_name {
get => _first_name;
set {
_first_name = value;
// This tells XAML there was a change.
// Makes "{Binding first_name}" work dynamically.
OnPropertyChanged();
}
}
private string _first_name;
}
OPTION B:
Didn't find an answer anywhere that does everything correctly, so here is a complete sample, for future reference:
Remove Kids.SetBinding(...). (It can be fixed as shown in OPTION A, but its easier to get it correct in XAML, so below I show it in XAML.)
Bindings from Page to VM. See xaml below.
Create ObservableCollection with setter that does OnPropertyChanged. This informs XAML when the list is ready, so page updates. (This is an implementation of INotifyPropertyChanged, as Jason mentioned.)
Use Device.BeginInvokeOnMainThread(async () to create an async context, that is queued to run after constructor returns. (This fixes the issue Jason mentioned, which is that a constructor isn't an async context, so should not DIRECTLY call an async method such as QueryItemsAsync, or your GetKids.) This is more reliable.
PageWithQueryData.xaml:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TestXFUWP.PageWithQueryData">
<ContentPage.Content>
<StackLayout>
<CollectionView ItemsSource="{Binding Items}">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Label Text="{Binding Name}" />
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
<CollectionView.EmptyView>
<Grid>
<Label Text="Loading ..." FontSize="24" TextColor="Blue" BackgroundColor="LightBlue" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" />
</Grid>
</CollectionView.EmptyView>
</CollectionView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
PageWithQueryData.xaml.cs:
public partial class PageWithQueryData : ContentPage
{
public PageWithQueryData()
{
InitializeComponent();
// ... other initialization work here ...
// BUT remove `Kids.Binding(...);` line. See XAML: `ItemsSource="{Binding Items}"`.
BindingContext = new VMWithQueryData();
}
}
VMWithQueryData.cs:
class VMWithQueryData : Xamarin.Forms.BindableObject
{
public VMWithQueryData()
{
// Start an async task to query.
Xamarin.Forms.Device.BeginInvokeOnMainThread(async () => {
await QueryItemsAsync();
});
// Alternative implementation: Start a background task to query.
//QueryItemsInBackground();
}
public ObservableCollection<ItemModel> Items {
get => _items;
set {
_items = value;
OnPropertyChanged();
}
}
private ObservableCollection<ItemModel> _items;
private async Task QueryItemsAsync()
{
var names = new List<string> { "One", "Two", "Three" };
bool queryOneAtATime = false;// true;
if (queryOneAtATime) {
// Show each item as it is available.
Items = new ObservableCollection<ItemModel>();
foreach (var name in names) {
// Simulate slow query - replace with query that returns one item.
await Task.Delay(1000);
Items.Add(new ItemModel(name));
}
} else {
// Load all the items, then show them.
// Simulate slow query - replace with query that returns all data.
await Task.Delay(3000);
var items = new ObservableCollection<ItemModel>();
foreach (var name in names) {
items.Add(new ItemModel(name));
}
Items = items;
}
}
// Alternative implementation, using a background thread.
private void QueryItemsInBackground()
{
Task.Run(() => {
var names = new List<string> { "One", "Two", "Three" };
bool queryOneAtATime = false;// true;
if (queryOneAtATime) {
// Show each item as it is available.
Items = new ObservableCollection<ItemModel>();
foreach (var name in names) {
// Simulate slow query - replace with query that returns one item.
System.Threading.Thread.Sleep(1000);
Items.Add(new ItemModel(name));
}
} else {
// Load all the items, then show them.
// Simulate slow query - replace with query that returns all data.
System.Threading.Thread.Sleep(3000);
var items = new ObservableCollection<ItemModel>();
foreach (var name in names) {
items.Add(new ItemModel(name));
}
Items = items;
}
});
}
}
ItemModel.cs:
public class ItemModel
{
public ItemModel(string name)
{
Name = name;
}
public string Name { get; set; }
}
This also demonstrates <CollectionView.EmptyView> to display a message to user, while the data is being queried.
For completeness, I've included an alternative QueryItemsInBackground, that uses a background thread instead of an async method. Either approach works well.
Notice inheritance from Xamarin.Forms.BindableObject. This is one way to get an implementation of INotifyPropertyChanged. You can use any other MVVM library or technique.
Move this line of code to the end of your constructor
this.BindingContext = viewmodel;

How do I get the id from a XAML ListView when more than one table is used?

I am populating a ListView with SQLite data from two or more tables. When selecting from table I wish to get the ID of the selected item but lv.SelectedItem is returning a null value. No trouble with single tables.
I have searched everywhere and most people are just having problems joining the tables and haven't got as far as selecting.
Classes
public int ShoppingListID
{
get { return listID; }
set { listID = value;}
}
public int ShopID
{
get { return shopID; }
set { shopID = value; }
}
public int ShopID
{
get { return shopID; }
set { shopID = value; }
}
public string ShopName
{
get { return shopName; }
set { shopName = value; }
}
Join code (which works perfectly)
using (SQLiteConnection conn = new SQLiteConnection(App.DatabaseLocation))
{
var allList = (from s in conn.Table<ShoppingLists>() join p in
conn.Table<Shops>() on s.ShopID equals
p.ShopID select new
{
s.ShoppingListID,
p.ShopName
}).ToList();
lvShoppingLists.ItemsSource = allList;
}
Bound to a Grid in XAML
<ListView x:Name="lvShoppingLists"
ItemSelected="LvShoppingLists_ItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<Label Grid.Column="0"
TextColor="Black"
Text="{Binding ShoppingListID}" />
<Label Grid.Column="1"
TextColor="Black"
Text="{Binding ShopName}" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Obtain the ID of the selected item
private void LvShoppingLists_ItemSelected(object sender,
SelectedItemChangedEventArgs e)
{
var selectedList = lvShoppingLists.SelectedItem as ShoppingLists;
GlobalVariables.SelectedShoppingListID = selectedList.ShoppingListID;
Navigation.PushAsync(new ShoppingListPage());
}
Everything compiles and runs fine, but upon selecting an item from the ListView on the mainpage var selectedList returns a null.
Debug shows that the information (id and Name) is being carried to the selected item but not being converted.
The null value means that the variable is unable to be used in the query for the new page and I get a database error.
I suspect that it is to do with the fact that the the class Shopping list has two int entries and the name is causing the problem.
Answer turns out to be:
Use a new class AllLists
public int ShoppingListID
{
get { return listID; }
set { listID = value; }
}
public string ShopName
{
get { return shopName; }
set { shopName = value; }
}
using (SQLiteConnection conn = new SQLiteConnection(App.DatabaseLocation))
{
var allList = (from s in conn.Table<ShoppingLists>() join p in
conn.Table<Shops>() on s.ShopID equals
p.ShopID select new **AllLists**
{
ShoppingListID = s.ShoppingListID,
ShopName = p.ShopName
});
lvShoppingLists.ItemsSource = allList;
}
The selected item ID can then be
var selectedList = lvShoppingLists.SelectedItem as AllLists;
GlobalVariables.SelectedShoppingListID = selectedList.ShoppingListID;
Navigation.PushAsync(new ShoppingListPage());

How do I check on the properties of WPF elements whilst in a different class?

I am following a bunch of different examples etc and trying to do my own thing with that.
Essentially, in my code behind, I have a separate class. I think this is being used for MVVM, though I have almost no idea what that kind of means (I get the point, but it looks confusing!).
Anyway... Here is my code in a seperate class (same namespace) to the code behind for my WPF form:
public class ChartViewModel
{
public ChartViewModel()
{
DataTable dataNames = new DataTable();
try
{
var db = new SQLiteDatabase();
string query = "SELECT DISTINCT Name FROM Main";
...
Now, I have a textblock on my WPF xaml page, named AccountType. The text within this can cycle between three different values, and I need to change the string query at the end of that code block above based on that. If it is one value, the string = x. if its the second value, the string = y etc...
That part of the class is used to populate a combobox with entries from a database. Will changing that string then automatically force the combobox to update? Or will I ned to do something else after this also?
As requested, here is my XAML (the relevant stuff anyway)
<ComboBox x:Name="NameBox" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" ItemsSource="{Binding Names}" Width="100" />
<Grid Grid.Row="0" Grid.Column="1">
<ProgressBar x:Name="AccountTypeProgress" Width="70" Height="20" MouseDown="AccountTypeButton_Click" />
<TextBlock x:Name="AccountType" Text="Main" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="#FF252525" FontSize="16" FontWeight="Bold" MouseDown="AccountTypeButton_Click" />
</Grid>
Full ViewModel
public class ChartViewModel
{
public ChartViewModel()
{
AccountType = "Main";
DataTable dataNames = new DataTable();
try
{
var db = new SQLiteDatabase();
string query = "SELECT DISTINCT Name FROM Main";
dataNames = db.GetDataTable(query);
}
catch (Exception fail)
{
string error = "The following error has occured:\n\n";
//error += fail.Message.ToString() + "\n\n";
//System.Windows.MessageBox.Show(error);
}
this.Names = new ObservableCollection<string> { };
foreach (DataRow row in dataNames.Rows)
{
string name = row["Name"].ToString();
Names.Add(name);
}
int x = 42067;
DataTable datastats = new DataTable();
try
{
var db = new SQLiteDatabase();
String query = "SELECT * FROM Main WHERE Name = \"9n\"";
datastats = db.GetDataTable(query);
}
catch (Exception fail)
{
String error = "The following error has occurred:\n\n";
//error += fail.Message.ToString() + "\n\n";
//System.Windows.MessageBox.Show(error);
}
this.overall = new List<DataPoint>
{
//foreach(DataRow row in datastats.Rows)
//{
//}
};
foreach (DataRow row in datastats.Rows)
{
DateTime sDate = DateTime.Parse(row["Date"].ToString());
//int date = ((sDate.Year - 1900)) + sDate.Day;
sDate = sDate.Date;
double date = sDate.ToOADate() - 1;
int dateint = Convert.ToInt32(date);
string sLevel = row["OverallL"].ToString();
int level = Convert.ToInt32(sLevel);
this.overall.Add(new DataPoint(date, level));
}
this.overall.Add(new DataPoint(42100, 10));
this.overall.Add(new DataPoint(42110, 10));
this.Title2 = "Example 2";
this.Points = new List<DataPoint>
{
new DataPoint(x, 4),
new DataPoint(42077, 13),
new DataPoint(42087, 15),
new DataPoint(42097, 16),
new DataPoint(42107, 12),
new DataPoint(42117, 12)
};
this.Data = new List<DataPoint>
{
new DataPoint(42067, 10),
new DataPoint(42077, 15),
new DataPoint(42087, 16),
new DataPoint(42097, 20),
new DataPoint(42107, 10),
new DataPoint(42117, 12)
};
}
public string Title2 { get; private set; }
public IList<DataPoint> Points { get; private set; }
public IList<DataPoint> Data { get; private set; }
public IList<DataPoint> overall { get; private set; }
public ObservableCollection<string> Names { get; private set; }
private string _AccountType;
public string AccountType
{
get { return _AccountType; }
set
{
_AccountType = value;
//OnPropertyChanged stuff here.
}
}
}
Firstly, in your ViewModel, you can create a property for your AccountType textblock to bind to:
private string _AccountType;
public string AccountType
{
get { return _AccountType; }
set
{
_AccountType = value;
//OnPropertyChanged stuff here.
}
}
When you cycle the account types, update this property, it will also update the UI.
You first need to set the binding on your TextBlock:
<TextBlock Text="{Binding AccountType}" ... />
Then you can simply use this property in your query.
That part of the class is used to populate a combobox with entries from a database. Will changing that string then automatically force the combobox to update? Or will I ned to do something else after this also?
It's good practice to use an ObservableCollection for lists that you are binding to from your UI. If you are not using this already, then please do so, as it handles the property changed stuff for you, and will update the bindings when an item is added/removed from the list.
Please let me know if I have missed anything.

wpf combo box SelectedValue = null issue

I got a combo box in wpf form
I set the ItemSource to the collection of Dictionary of (Pet Type) and just display the Value and hid the Key
public void BindComboBoxes()
{
this.cboTypes.ItemsSource = new BindingSource(CommonMgr.GetPetTypesDropDown(false), null);
this.cboTypes.DisplayMemberPath = "Value";
this.cboTypes.SelectedValuePath = "Key";
}
Then whenever I type to encode a new Breed Object, and type a text in the cboTypes of something that doesn't exist in its items(not in the db), my program will ask if the end user wants to add that new PetType in the db, if yes, then it will do so.
Then i update the cboTypes using the BindComboBoxes method again, set the cboTypes.Text into the new item and assign the Key to the designated field, but the problem is, it says, it was null. it worked fine in the windows form though. Here's my code:
public Breed GetPageEntity()
{
Breed setEntity = new Breed();
bool doesExist = false;
setEntity.Id = DefaultValue.GetInt(this.txtId.Text);
setEntity.BreedName = DefaultValue.GetString(this.txtName.Text);
try
{
setEntity.PetTypeId = DefaultValue.GetInt(this.cboTypes.SelectedValue.ToString());
}
catch (Exception)
{
var addAnother = MessageBox.Show(String.Format("{0}: This type is not in the database. \nAdd {0} to the database?",
this.cboTypes.Text), "Pet Type Cannot Be Found", MessageBoxButtons.OKCancel);
if (addAnother == System.Windows.Forms.DialogResult.OK)
{
petTypeMgr.Entity = this.PetTypeAdder(cboTypes.Text);
string temp = this.cboTypes.Text;
petTypeMgr.Insert((petTypeMgr.Entity), fUser.Entity.Id, ref doesExist);
//cboTypes.ItemsSource = null;
//cboTypes.Items.Clear();
BindComboBoxes();
cboTypes.Text = temp;
//SelectedValue became null
setEntity.PetTypeId = DefaultValue.GetInt(this.cboTypes.SelectedValue);
}
}
setEntity.Description = DefaultValue.GetString(this.txtDescription.Text);
setEntity.SortOrder = DefaultValue.GetInt(txtSortOrder.Text);
setEntity.StatusId = true;
return setEntity;
}
You'll find it much easier if you data bind to properties in the code behind:
// Implement INotifyPropertyChanged interface properly here
private Dictionary<string, Pet> yourProperty = new Dictionary<string, Pet>();
public Dictionary<string, Pet> YourProperty
{
get { return yourProperty; }
set
{
yourProperty = value;
NotifyPropertyChanged("YourProperty");
}
}
private KeyValuePair<string, int> yourSelectedProperty;
public KeyValuePair<string, int> YourSelectedProperty
{
get { return yourSelectedProperty; }
set
{
yourSelectedProperty = value;
NotifyPropertyChanged("YourSelectedProperty");
}
}
Then in the XAML:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ComboBox ItemsSource="{Binding YourProperty}" DisplayMemberPath="Value"
SelectedValuePath="Key" SelectedItem="{Binding YourSelectedProperty}" />
<TextBlock Grid.Column="1" Text="{Binding YourSelectedProperty.Key}" />
</Grid>
You only need to set your ItemsSource once like this. Once it is data bound to a collection property, you can just make changes to the collection and they will update in the UI automatically. So, assuming that your GetPetTypesDropDown method returns the correct type, you should be able to update the ComboBox items like this:
YourProperty = CommonMgr.GetPetTypesDropDown(false);
Alternatively, you could equally do something like this to update it:
YourProperty = new Dictionary<string, int>();
foreach (YourDataType dataType in CommonMgr.GetPetTypesDropDown(false))
{
YourProperty.Add(dataType.Key, dataType.Value);
}
Why don't you just bind Breed to the Combobox?
In the Breed class override the ToString() method so that the box shows what you want it to.
class Breeds
{
//Variables
public void override ToString()
{
return Breedname;
}
}
Set the combobox
List<Breeds> breedlist = new List<Breeds>();
this.cboTypes.ItemsSource = breedlist;
Read the combobox
if(cboTypes.SelectedItem != null)
{
Breeds breed = (Breeds)cboTypes.SelectedItem;
//Do stuff
}
else
{
//Create new breed
}

Silverlight/WPF unable to bind ListBox

I have a listbox in my silverlight usercontrol and I am filling it with a generic list of a private class, for some reason it is not being databound.
Here is the code :
class userClient
{
public int characterID { get; set; }
public string characterName { get; set; }
}
List<userClient> userClientList; // = new List<userClient>();
void _client_UserList(object sender, DataTransferEventArgs e)
{
this.Dispatcher.BeginInvoke(() =>
{
userClientList = new List<userClient>();
foreach (string user in e.DataTransfer.Data)
{
var userDetailsArray = user.Split('+');
userClient uc = new userClient
{
characterID = Convert.ToInt32(userDetailsArray[0]),
characterName = userDetailsArray[1]
};
userClientList.Add(uc);
}
chatUsers.ItemsSource = userClientList;
chatUsers.DisplayMemberPath = "characterName";
});
}
I checked the generic list userClientList and it is being filled up so there is no problems there.
This is the XAML of the listbox:
<ListBox x:Name="chatUsers" Grid.Row="0" Grid.Column="1" Margin="2 2 2 2" />
Do you have any binding errors messages logged in Output Window in Visual Studio?
Edit:
Just noticed that your collection is a field while it should be public property
public ObservableCollection<userClient> userClientList { get; set; }
Thank you! Thank you Mokosh! The error --
System.Windows.Data Error: 39 : BindingExpression path error --
drove me crazy through two WPF books without finding the answer that you emphasized --
I didn't create properties on my class members.

Categories

Resources