Reputation: 115
I know this is basic, but I'm making the jump from vb.net to C#, and the approach I was using in vb.net doesn't seem to be working.
I've created a .dll with a custom class Service.
In my project, I'm populating an ObservableCollection with instances of Service. I want to display the instances in a combobox using DisplayMemberPath in XAML (WPF).
My instances of Service are populating the ComboBox, but the display for each item is blank; I'm just getting a bunch of blank lines to choose from.
I've tried this with and without implementing INotifyPropertyChanged on the class itself, although I don't think it should be necessary at this point since I'm still pretty much at square 1.
Here's my code:
<Grid>
<ComboBox Name="TopService"
VerticalAlignment="Top"
ItemsSource="{Binding}"
DisplayMemberPath="{Binding ServCode}"></ComboBox>
</Grid>
And here's my code behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Execute();
}
private void Execute()
{
SA.franchiseID = "HOL010";
ObservableCollection<Service> ocService = Service.InitializeServiceList();
TopService.DataContext = ocService;
}
}
And the code for the class (referenced via .dll)
public class Service : INotifyPropertyChanged
{
#region INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
protected void Notify(string propertyName)
{
if (this.PropertyChanged != null)
{ PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); }
}
#endregion
private string servCode;
public string ServCode
{
get { return servCode; }
set { servCode = value; Notify("ServCode"); }
}
public string programCode = "";
public int roundNum = 0;
public static ObservableCollection<Service> InitializeServiceList()
{
ObservableCollection<Service> oc = new ObservableCollection<Service>();
using (SA s = new SA())
{
s.SqlString = @"select
ps.serv_code
,pc.prgm_code
,ps.round
from prgmserv as ps
inner join prgmcd as pc on pc.progdefid = ps.progdefid
where pc.available = 1";
s.reader = s.command.ExecuteReader();
Service newService;
while (s.reader.Read())
{
newService = new Service();
newService.servCode = s.reader["serv_code"].ToString();
newService.programCode = s.reader["prgm_code"].ToString();
newService.roundNum = Convert.ToInt32(s.reader["round"].ToString());
oc.Add(newService);
newService = null;
}
return oc;
}
}
}
Upvotes: 2
Views: 1226
Reputation: 115
I have also come to realize while attempting to bind items to an ItemsControl, that the difference between a Field and a Property become very important. I have been trying to bind to Fields, which does not work. This is technically not different than in VB.net. But an implicitly defined Property in VB.net looks very much like a Field in C#. All that said, I believe I'm ready to go conquer the world now!
Upvotes: 1
Reputation: 37059
DisplayMemberPath
is a string. You don't give it a binding to a property; you just give it a path to a property, which it then looks up by reflection.
Try this:
DisplayMemberPath="ServCode"
What you were doing would make it use the value of ServCode
as a DisplayMemberPath
; if ServCode is 12
, it would look for a property named 12
on each item in the combobox -- not your intent, I'm sure.
Upvotes: 6