This question is locked. New answers and comments are not allowed.
Having some issues with using the RadDataboundListbox.
I'm using a simple ViewModel that calls an "OnNotifyPropertyChanged" method that, in turn, fires the PropertyChanged event for a list of custom objects. When I use a regular ListBox there isn't any problem...it works fine. When I use the RadDataboundListBox I get an exception when the PropertyChanged event attempts to create a new PropertyChangedEventArgs with the name of the property passed in as a string. I get "The parameter is incorrect".
I originally thought that this was something I was doing because I had a more complicated scenario where the view model was getting created globally. I changed that and I still have the problem.
Also, if I used the RadDataBoundListBox without an itemtemplate and without a datatemplate (using DisplayMemberPath to display listbox items) all was well. The problem seemed to start when I added the data template.
(Edit: I just tested this again - using only DisplayMemberPath - and the problem still occurs.)
I've included here the XAML snippet that includes the RadDataboundListbox and the commented ListBox (I have an identical listbox commented out. That is the piece that works). I've also included code for the view model - but I had to censor the "apikey" variable that I use. This particular application calls out to the NY Times API and that key is assigned to me, so I can't share it. Finally, I included the code-behind for the page. (I've commented out portions of code that were being used to save state for tombstoning purposes...because I thought that might have been a problem as well.)
To add a bit more detail..the listbox is populated after a button press calls the GetMembers() method in the view model. The Session and Chamber properties in the view model are bound to the RadListPicker SelectedItem properties and that is all working fine. There are values in those properties otherwise there would be an issue with the GetMembers() method. The issue doesn't manifest itself until the Members collection attempts a notification that it has changed.
That's about it. Thanks in advance for any guidance.
I'm using a simple ViewModel that calls an "OnNotifyPropertyChanged" method that, in turn, fires the PropertyChanged event for a list of custom objects. When I use a regular ListBox there isn't any problem...it works fine. When I use the RadDataboundListBox I get an exception when the PropertyChanged event attempts to create a new PropertyChangedEventArgs with the name of the property passed in as a string. I get "The parameter is incorrect".
I originally thought that this was something I was doing because I had a more complicated scenario where the view model was getting created globally. I changed that and I still have the problem.
Also, if I used the RadDataBoundListBox without an itemtemplate and without a datatemplate (using DisplayMemberPath to display listbox items) all was well. The problem seemed to start when I added the data template.
(Edit: I just tested this again - using only DisplayMemberPath - and the problem still occurs.)
I've included here the XAML snippet that includes the RadDataboundListbox and the commented ListBox (I have an identical listbox commented out. That is the piece that works). I've also included code for the view model - but I had to censor the "apikey" variable that I use. This particular application calls out to the NY Times API and that key is assigned to me, so I can't share it. Finally, I included the code-behind for the page. (I've commented out portions of code that were being used to save state for tombstoning purposes...because I thought that might have been a problem as well.)
To add a bit more detail..the listbox is populated after a button press calls the GetMembers() method in the view model. The Session and Chamber properties in the view model are bound to the RadListPicker SelectedItem properties and that is all working fine. There are values in those properties otherwise there would be an issue with the GetMembers() method. The issue doesn't manifest itself until the Members collection attempts a notification that it has changed.
That's about it. Thanks in advance for any guidance.
<
telerikPrimitives:RadDataBoundListBox
x:Name
=
"lboMembers"
Grid.Row
=
"1"
Grid.Column
=
"0"
Grid.ColumnSpan
=
"3"
ItemsSource
=
"{Binding Members}"
SelectionChanged
=
"lboMembers_SelectionChanged"
>
<
telerikPrimitives:RadDataBoundListBox.ItemTemplate
>
<
DataTemplate
>
<
Grid
>
<
Grid.ColumnDefinitions
>
<
ColumnDefinition
Width
=
"Auto"
/>
<
ColumnDefinition
Width
=
"Auto"
/>
<
ColumnDefinition
Width
=
"Auto"
/>
</
Grid.ColumnDefinitions
>
<
TextBlock
Grid.Column
=
"0"
Text
=
"{Binding FullName}"
Width
=
"300"
Style
=
"{StaticResource PhoneTextNormalStyle}"
/>
<
TextBlock
Grid.Column
=
"1"
Text
=
"{Binding State}"
Style
=
"{StaticResource PhoneTextNormalStyle}"
/>
<
TextBlock
Grid.Column
=
"2"
Text
=
"{Binding Party}"
Style
=
"{StaticResource PhoneTextNormalStyle}"
/>
</
Grid
>
</
DataTemplate
>
</
telerikPrimitives:RadDataBoundListBox.ItemTemplate
>
</
telerikPrimitives:RadDataBoundListBox
>
<!--<
ListBox
x:Name
=
"lboMembers"
Grid.Row
=
"1"
Grid.Column
=
"0"
Grid.ColumnSpan
=
"3"
ItemsSource
=
"{Binding Members}"
SelectionChanged
=
"lboMembers_SelectionChanged"
>
<
ListBox.ItemTemplate
>
<
DataTemplate
>
<
Grid
>
<
Grid.ColumnDefinitions
>
<
ColumnDefinition
Width
=
"Auto"
/>
<
ColumnDefinition
Width
=
"Auto"
/>
<
ColumnDefinition
Width
=
"Auto"
/>
</
Grid.ColumnDefinitions
>
<
TextBlock
Grid.Column
=
"0"
Text
=
"{Binding FullName}"
Width
=
"300"
Style
=
"{StaticResource PhoneTextNormalStyle}"
/>
<
TextBlock
Grid.Column
=
"1"
Text
=
"{Binding State}"
Style
=
"{StaticResource PhoneTextNormalStyle}"
/>
<
TextBlock
Grid.Column
=
"2"
Text
=
"{Binding Party}"
Style
=
"{StaticResource PhoneTextNormalStyle}"
/>
</
Grid
>
</
DataTemplate
>
</
ListBox.ItemTemplate
>
</
ListBox
>-->
public
class
MembersVM : INotifyPropertyChanged
{
private
readonly
string
uriStart =
"http://api.nytimes.com/svc/politics/v3/us/legislative/congress/"
;
private
readonly
string
apiKey =
"cannot share this value....."
;
private
string
uriString;
public
MembersVM()
{
uriString = uriStart +
"{0}/{1}/members.xml?api-key="
+ apiKey;
}
#region Methods
public
void
GetMembers()
{
uriString =
string
.Format(uriString, Session, Chamber);
Uri serviceUri =
new
Uri(uriString);
WebClient client =
new
WebClient();
//IsBusy = true;
client.OpenReadAsync(serviceUri);
client.OpenReadCompleted += (s, e) =>
{
List<Member> tmpList =
new
List<Member>();
ObservableCollection<Member> obsvHolder =
new
ObservableCollection<Member>();
if
(e.Error !=
null
)
{
// add error message, logging, etc...
string
sError = e.Error.Message;
}
else
{
using
(Stream st = e.Result)
{
XDocument doc = XDocument.Load(st);
foreach
(var x
in
doc.Descendants(
"member"
))
{
tmpList.Add(CreateValidMember(x));
}
// Order by state
var query = from m
in
tmpList
orderby m.State
select m;
tmpList = query.ToList();
// Convert list to ObservableCollection
foreach
(var member
in
tmpList)
{
member.FullName = member.FirstName +
" "
+ member.LastName;
obsvHolder.Add(member);
}
// Set the property
Members = obsvHolder;
}
}
//IsBusy = false;
};
}
private
Member CreateValidMember(XElement e)
{
Member m =
new
Member();
m.Id = e.Element(
"id"
).Value;
m.FirstName = e.Element(
"first_name"
).Value;
m.LastName = e.Element(
"last_name"
).Value;
m.Party = e.Element(
"party"
).Value;
m.State = e.Element(
"state"
).Value;
m.ApiUrl = e.Element(
"api_uri"
).Value;
m.Seniority = e.Element(
"seniority"
) !=
null
?
Convert.ToInt32(e.Element(
"seniority"
).Value) : 0;
m.NextElection = e.Element(
"next_election"
) !=
null
?
Convert.ToInt32(e.Element(
"next_election"
).Value) : 0;
m.MissedPct = e.Element(
"missed_votes_pct"
) !=
null
?
Convert.ToDouble(e.Element(
"missed_votes_pct"
).Value) : 0;
m.PartyLineVote = e.Element(
"votes_with_party_pct"
) !=
null
?
Convert.ToDouble(e.Element(
"votes_with_party_pct"
).Value) : 0;
m.District = Chamber.Equals(
"House"
) ?
Convert.ToInt32(e.Element(
"district"
).Value) : 0;
return
m;
}
#endregion
#region Properties
private
ObservableCollection<Member> members;
public
ObservableCollection<Member> Members
{
get
{
return
members; }
set
{
if
(members != value)
{
members = value;
//this.NotifyPropertyChanged(m => m.Members);
OnNotifyPropertyChanged(
"Members"
);
}
}
}
private
string
session;
public
string
Session
{
get
{
return
session; }
set
{
if
(session != value)
{
session = value;
//this.NotifyPropertyChanged(m => m.Session);
OnNotifyPropertyChanged(
"Session"
);
}
}
}
private
string
chamber;
public
string
Chamber
{
get
{
return
chamber; }
set
{
if
(chamber != value)
{
chamber = value;
//this.NotifyPropertyChanged(m => m.Chamber);
OnNotifyPropertyChanged(
"Chamber"
);
}
}
}
private
Member selectedMember;
public
Member SelectedMember
{
get
{
return
selectedMember; }
set
{
if
(selectedMember != value)
{
selectedMember = value;
//this.NotifyPropertyChanged(m => m.SelectedMember);
OnNotifyPropertyChanged(
"SelectedMember"
);
}
}
}
#endregion
#region INotifyPropertyChanged Members
public
event
PropertyChangedEventHandler PropertyChanged;
#endregion
public
void
OnNotifyPropertyChanged(
string
p)
{
if
(PropertyChanged !=
null
)
{
PropertyChanged(
this
,
new
PropertyChangedEventArgs(p));
}
}
}
public
partial
class
MainPage : PhoneApplicationPage
{
private
MembersVM vm;
// Constructor
public
MainPage()
{
InitializeComponent();
vm =
new
MembersVM();
DataContext = vm;
}
private
void
btnGo_Click(
object
sender, RoutedEventArgs e)
{
vm.GetMembers();
}
private
void
lboMembers_SelectionChanged(
object
sender, SelectionChangedEventArgs e)
{
if
(lboMembers.SelectedItem !=
null
)
{
vm.SelectedMember = lboMembers.SelectedItem
as
Member;
NavigationService.Navigate(
new
Uri(
"/MemberDetail.xaml"
, UriKind.Relative));
}
}
//protected override void OnNavigatedFrom(NavigationEventArgs e)
//{
// State["members"] = App.AppVM.Members;
// State["session"] = App.AppVM.Session;
// State["chamber"] = App.AppVM.Chamber;
//}
//protected override void OnNavigatedTo(NavigationEventArgs e)
//{
// if (State.ContainsKey("members") && State.ContainsKey("session") && State.ContainsKey("chamber"))
// {
// App.AppVM.Members = State["members"] as ObservableCollection<Member>;
// App.AppVM.Session = State["session"] as string;
// App.AppVM.Chamber = State["chamber"] as string;
// }
//}
}