I am quite new to the concept of data binding and MVVM, so I've been trying it out the past couple of days. Basically, what I'm trying to do is using the LiveCharts library, I want to display multiple charts at the same time from an uploaded CSV file.
I am doing well so far, but now I am writing code so that if I want to increase the units in the X-Axis in one chart, I can do so simultaneously with the others. (For context, the x-axis is in the timestamp unit, and the different charts should have the same timestamp, but different IDs and different values under the same timestamp)
The code in my UI is like this (omitted some of the code I think is unnecessary):
<ItemsControl ItemsSource="{Binding SeriesViews}" VerticalAlignment="Top">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Background="White">
<lvc:CartesianChart Series="{Binding}" Pan="X">
<lvc:CartesianChart.AxisX>
<lvc:Axis RangeChanged="Axis_RangeChanged"
MinValue="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Grid}}, Path=DataContext.Xmin}"
MaxValue="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Grid}}, Path=DataContext.Xmax}"
Separator="{x:Static lvc:DefaultAxes.CleanSeparator}">
</lvc:Axis>
</lvc:CartesianChart.AxisX>
</lvc:CartesianChart>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
The other end is like this:
public GraphData gd;
public Graphs()
{
InitializeComponent();
}
public void GenerateCSVList(string csvPath)
{
using (var reader = new StreamReader(csvPath))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
ExcelRecords = csv.GetRecords<Emotions>().ToList();
}
gd = new GraphData();
gd.Xmin = 0;
gd.Xmax = 5;
gd.SeriesViews = ReturnChart();
this.DataContext = gd;
}
public ObservableCollection<SeriesCollection> ReturnChart()
{
ObservableCollection<SeriesCollection> ChartCollection = new ObservableCollection<SeriesCollection>();
//Draw charts here
return ChartCollection
}
public class GraphData : INotifyPropertyChanged
{
public ObservableCollection<SeriesCollection> SeriesViews { get; set; }
private double _xmin;
private double _xmax;
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName = null)
{
if (PropertyChanged != null)
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public double Xmin
{
get { return _xmin; }
set
{
_xmin = value;
OnPropertyChanged("Xmin");
}
}
public double Xmax
{
get { return _xmax; }
set
{
_xmax = value;
OnPropertyChanged("Xmax");
}
}
}
I'm currently getting this error though for both the min and max values:
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.Grid', AncestorLevel='1''. BindingExpression:Path=DataContext.Xmax; DataItem=null; target element is 'Axis' (Name=''); target property is 'MaxValue' (type 'Double')
I would appreciate a nudge in the right direction, since all of this is quite new to me. Is there something I missed with the binding? I thought by putting them in one class I would be able to access them from the UI. Why am I able to view the SeriesViews, but not the Xmin and Xmax from the same class?
The issue is definitely, that you don't have a Grid as parent container for your ItemsControl. Change the AncestorType to the ItemsControl and you will gert the binding working.
<lvc:Axis RangeChanged="Axis_RangeChanged"
MinValue="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.Xmin}"
MaxValue="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.Xmax}"
Separator="{x:Static lvc:DefaultAxes.CleanSeparator}">
</lvc:Axis>
Figured it out. The following is the working code:
<lvc:Axis RangeChanged="Axis_RangeChanged" DisableAnimations="True" Position="LeftBottom"
MinValue="{Binding DataContext.Xmin, Source={x:Reference Root}}"
MaxValue="{Binding DataContext.Xmax, Source={x:Reference Root}}"
Separator="{x:Static lvc:DefaultAxes.CleanSeparator}">
Where I named my UserControl as Root
Related
So I have an ItemsControl set in my xaml as such:
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<local:ToggleButton Command="{Binding DataContext.ItemSelectedCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type WrapPanel}}}"
CommandParameter="{Binding DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}}}"
Text="{Binding DataContext.ItemEnum, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}}, Converter={StaticResource EnumToStringConverter}}"
IsActive="{Binding DataContext.Selected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}}, UpdateSourceTrigger=PropertyChanged}"
Width="96"
Height="88"
Margin="5" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
I have the 4 dependency properties Command, CommandParameter, Text, and IsActive.
The first 3 dependency properties work correctly, the text is set, and the command callback works with the parameter.
The IsActive property however does NOT work.
The Items property in the main viewmodel is defined as:
List<ItemViewModel> Items { get; set; }
The ItemViewModel is defined as:
public class ItemViewModel : INotifyPropertyChanged
{
public ItemViewModel()
{
this.Selected = true;
}
private bool? _selected;
public event PropertyChangedEventHandler PropertyChanged;
public ItemEnum ItemEnum { get; set; }
public bool? Selected
{
get { return this._selected; }
set
{
this._selected = value;
this.OnPropertyChanged(nameof(this.Selected));
}
}
protected virtual void OnPropertyChanged(string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
the dependency property for the IsActive property in the ToggleButton.xaml.cs file looks like:
public static readonly DependencyProperty IsActiveProperty = DependencyProperty.Register(nameof(IsActive), typeof(bool?), typeof(ToggleButton), new PropertyMetadata(null, IsActiveSetCallback));
private static void IsActiveSetCallback(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var button = (ToggleButton)obj;
button.IsActive = (bool)(e.NewValue ?? e.OldValue);0xa5, 0xa5));
}
My command callback in the main view model looks like this:
this.ItemSelectedCommand =
new DelegateCommand(
itemVm =>
{
bool? setTo = !((ItemViewModel) itemVm).Selected;
this.Items.ForEach(i => i.Selected = false);
((ItemViewModel) itemVm).Selected = setTo;
});
Again, the other dependency properties (defined basically identically to IsActiveProperty) work correctly, so when I click the item, the above command gets called (verified by breakpoint), the item's Selected flag gets toggled properly, but the IsActiveSetCallback never gets hit. I can't see what I'm doing wrong, but clearly it's something.
Does anyone see something that I don't?
Thanks in advance!
After spending too much time trying to solve this, of course I manage to solve it myself within half an hour of posting this question..
I pulled this from the Microsoft DependencyProperty docs, specifically the section about 'Dependency Property Setting Precedence List':
Local value. A local value might be set through the convenience of the "wrapper" property, which also equates to setting as an attribute or property element in XAML, or by a call to the SetValue API using a property of a specific instance. If you set a local value by using a binding or a resource, these each act in the precedence as if a direct value was set.
So, I was setting this.Active in two places in the ToggleButton.xaml.cs, once in the constructor as a default value, and once in the IsActiveSetCallback .. turns out by doing that, I was overriding the binding, and neither of those calls were necessary anyways. So simple!
I have an ItemsControl that should display the values of some properties of an object.
The ItemsSource of the ItemsControl is an object with two properties: Instance and PropertyName.
What I am trying to do is displaying all the property values of the Instance object, but I do not find a way to set the Path of the binding to the PropertyName value:
<ItemsControl ItemsSource={Binding Path=InstanceProperties}>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=PropertyName, Mode=OneWay}"/>
<TextBlock Text=": "/>
<TextBlock Text="{Binding Source=??{Binding Path=Instance}??, Path=??PropertyName??, Mode=OneWay}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
the question marks are the points where I don't know how to create the binding.
I initially tried with a MultiValueConverter:
<TextBlock Grid.Column="1" Text="{Binding}">
<TextBlock.DataContext>
<MultiBinding Converter="{StaticResource getPropertyValue}">
<Binding Path="Instance" Mode="OneWay"/>
<Binding Path="PropertyName" Mode="OneWay"/>
</MultiBinding>
</TextBlock.DataContext>
</TextBlock>
The MultiValueConverter uses Reflection to look through the Instance and returns the value of the property.
But if the property value changes, this change is not notified and the displayed value remains unchanged.
I am looking for a way to do it with XAML only, if possible, if not I will have to write a wrapper class to for the items of the ItemsSource collection, and I know how to do it, but, since it will be a recurring task in my project, it will be quite expensive.
Edit:
For those who asked, InstanceProperties is a property on the ViewModel which exposes a collection of objects like this:
public class InstanceProperty : INotifyPropertyChanged
{
//[.... INotifyPropertyChanged implementation ....]
public INotifyPropertyChanged Instance { get; set; }
public string PropertyName { get; set; }
}
Obviously the two properties notify theirs value is changing through INotifyPropertyChanged, I don't include the OnPropertyChanged event handling for simplicity.
The collection is populated with a limited set of properties which I must present to the user, and I can't use a PropertyGrid because I need to filter the properties that I have to show, and these properties must be presented in a graphically richer way.
Thanks
Ok, thanks to #GazTheDestroyer comment:
#GazTheDestroyer wrote: I cannot think of any way to dynamically iterate and bind to an arbitrary object's properties in XAML only. You need to write a VM or behaviour to do this so you can watch for change notifications, but do it in a generic way using reflection you can just reuse it throughout your project
I found a solution: editing the ViewModel class InstanceProperty like this
added a PropertyValue property
listen to PropertyChanged event on Instance and when the PropertyName value changed is fired, raise PropertyChanged on PropertyValue
When Instance or PropertyName changes, save a reference to Reflection's PropertyInfo that will be used by PropertyValue to read the value
here is the new, complete, ViewModel class:
public class InstanceProperty : INotifyPropertyChanged
{
#region Properties and events
public event PropertyChangedEventHandler PropertyChanged;
private INotifyPropertyChanged FInstance = null;
public INotifyPropertyChanged Instance
{
get { return this.FInstance; }
set
{
if (this.FInstance != null) this.FInstance.PropertyChanged -= Instance_PropertyChanged;
this.FInstance = value;
if (this.FInstance != null) this.FInstance.PropertyChanged += Instance_PropertyChanged;
this.CheckProperty();
}
}
private string FPropertyName = null;
public string PropertyName
{
get { return this.FPropertyName; }
set
{
this.FPropertyName = value;
this.CheckProperty();
}
}
private System.Reflection.PropertyInfo Property = null;
public object PropertyValue
{
get { return this.Property?.GetValue(this.Instance, null); }
}
#endregion
#region Private methods
private void CheckProperty()
{
if (this.Instance == null || string.IsNullOrEmpty(this.PropertyName))
{
this.Property = null;
}
else
{
this.Property = this.Instance.GetType().GetProperty(this.PropertyName);
}
this.RaisePropertyChanged(nameof(PropertyValue));
}
private void Instance_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == this.PropertyName)
{
this.RaisePropertyChanged(nameof(PropertyValue));
}
}
private void RaisePropertyChanged(string propertyname)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
}
#endregion
}
and here is the XAML:
<ItemsControl ItemsSource={Binding Path=InstanceProperties}>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=PropertyName, Mode=OneWay}"/>
<TextBlock Text=": "/>
<TextBlock Text="{Binding Path=PropertyValue, Mode=OneWay}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
I want make TreeView with editable nodes. I googled this good, as I think, article:
http://www.codeproject.com/Articles/31592/Editable-TextBlock-in-WPF-for-In-place-Editing
But I have a problems. My TreeView formed dinamically, not statically as in the arcticle. Like that
<TreeView Name="_packageTreeView" Margin="5" ItemsSource="{Binding PackageExtendedList}">
<TreeView.InputBindings>
<KeyBinding Key="C" Command="{Binding *TestCommand*}" CommandParameter="{Binding}" />
</TreeView.InputBindings>
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectedItemChanged">
<i:InvokeCommandAction Command="{Binding PackageTreeItemChangeCommand}" CommandParameter="{Binding ElementName=_packageTreeView, Path=SelectedItem}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" />
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type MasterBuisnessLogic:RootDocPackage}" ItemsSource="{Binding Path=Childs}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition>
</ColumnDefinition>
<ColumnDefinition>
</ColumnDefinition>
</Grid.ColumnDefinitions>
<Image Source="/Resources/DocGroup.png"></Image>
<Etb:EditableTextBlock Margin="5,0,0,0" Grid.Column="1" Text="{Binding Path=Name}"></Etb:EditableTextBlock>
</Grid>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
PackageExtendedList - List of DocPackageExtended.
So, first question - how can I get TreeViewItem instance in TestCommand? Not instance DocPackageExtended class! I want to get instance selected TreeViewItem like in the article.
And second question - After I get instance TreeViewItem, how can I get EditableTextBlock from the TreeView item's DataTemplate.
added answer
I already tried it. Cause in MVVM ViewModel cannot has any link to View object like TreeView, I make handler in code-behind, like that
private void TreeViewItemSelected(object sender, RoutedEventArgs e)
{
// Already have TreeViewItem instance without of ItemContainerGenerator help
var tvi = e.OriginalSource as TreeViewItem;
if (tvi == null)
return;
var etb = VisualTreeLib.VisualTreeLib.GetVisualChild<EditableTextBlock>(tvi);
if (etb == null)
return;
// Do what I want
etb.IsEditable = true;
}
Unfortunately, this has no any affect :(
I also tried that approach, but also failed.
in DocPackageExtended type I define property
public bool IsEditable
{
get { return _isEditable; }
set
{
_isEditable = value;
OnPropertyChanged(new PropertyChangedEventArgs("IsEditable"));
}
}
than change in XAML:
<Etb:EditableTextBlock Margin="5,0,0,0" Grid.Column="1" Text="{Binding Path=Name}" *IsEditable="{Binding Path=IsEditable}"*/>
and in ViewModel
private void TestCommandMethod(object obj)
{
var dpe = obj as DocPackageExtended;
if (dpe == null)
return;
dpe.IsEditable = true;
}
Doesn't work too :(
Any ideas?
This might help you.
private void Button_Click(object sender, RoutedEventArgs e)
{
TreeViewItem treeViewItemFound = GetItem(MyTreeview, MyTreeview.SelectedItem);
ContentPresenter header = treeViewItemFound.Template.FindName("PART_Header", treeViewItemFound) as ContentPresenter;
if (header != null)
{
TextBox myTextBox = (TextBox)header.ContentTemplate.FindName("MyTextBox", header);
}
}
public TreeViewItem GetItem(ItemsControl container, object itemToSelect)
{
foreach (object item in container.Items)
{
if (item == itemToSelect)
{
return (TreeViewItem)container.ItemContainerGenerator.ContainerFromItem(item);
}
else
{
ItemsControl itemContainer = (ItemsControl)container.ItemContainerGenerator.ContainerFromItem(item);
if (itemContainer.Items.Count > 0)
{
TreeViewItem treeViewItemFound = GetItem(itemContainer, itemToSelect);
if (treeViewItemFound != null)
return treeViewItemFound;
}
}
}
return null;
}
First question: Since it seems that you can select multiple entries, you need to filter all selected entries in TestCommand's executed method:
IEnumerable<DocPackageExtended> selectedEntries = PackageExtendedList.Where(d => d.IsSelected);
If multiple selection is disabled, you could bind the TreeView's selected item to a property in your VM and access this property in TestCommand's method.
Second question: You get the dataitem's container through var container = YourTreeViewInstance.ItemContainerGenerator.ContainerFromItem(dataInstance);. Now you have to go through this container with the help of the VisualTreeHelper until it finds a control of type EditableTextBlock. But I wouldn't do this in a ViewModel, rather in a helper-class or with the help of attached properties.
EDIT: You're binding the IsEditable property of the instances in the Childs property of your DocPackageExtended class to your EditableTextBox, but in your TestCommandMethod you're manipulating the IsEditableproperty of a DocPackageExtended instance directly. You could do the following:
private void TestCommandMethod(object obj)
{
var dpe = obj as DocPackageExtended;
if (dpe == null)
return;
dpe.IsEditable = true;
foreach (RootDocPackage rdp in dpe.Childs)
{
rdp.IsEditable = true;
}
}
Control template:
<ControlTemplate x:Key="BasicShape2">
<StackPanel Name="sp">
<Border Name="bd" CornerRadius="3.5" BorderThickness="1" BorderBrush="{Binding RelativeSource={RelativeSource TemplatedParent},Path=DataContext.NodeType, Converter={StaticResource NodeTypeColorConverter}, Mode=OneWay}" Height="32" Padding="1">
<TextBlock Name="tbName" Grid.Column="1" Text="" HorizontalAlignment="Center" VerticalAlignment="Bottom" FontSize="16" />
</Border>
</StackPanel>
</ControlTemplate>
a class which this template will apply to:
public class MyThumbEx : Thumb
{
public static readonly DependencyProperty MemberInfoProperty = DependencyProperty.Register("MemberInfo", typeof(FamilyMemberInfo), typeof(MyThumbEx));
public FamilyMemberInfo MemberInfo
{
get { return (FamilyMemberInfo)GetValue(MemberInfoProperty); }
set { SetValue(MemberInfoProperty, value); }
}
public MyThumbEx(ControlTemplate template, FamilyMemberInfo info, Point position)
{
this.MemberInfo = info;
this.DataContext = this.MemberInfo;
this.Template = template;
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
this.ApplyTextContent();
}
public void ApplyTextContent()
{
TextBlock tbName = this.Template.FindName("tbName", this) as TextBlock;
if (tbName != null)
{
tbName.Text = this.MemberInfo.Name;
}
}
}
initialize and display it on a canvas:
public MainWindow()
{
InitializeComponent();
//
FamilyMemberInfo mi = new FamilyMemberInfo();
mi.Name = "someone";
mi.ID = "id1";
MyThumbEx te = new MyThumbEx(Application.Current.Resources["BasicShape2"] as ControlTemplate, mi, new Point(0, 0));
//
this.cvMain.Children.Add(te);
}
These codes work fine, but be noticed that in the control template, I have to set Path=DataContext.NodeType, not just Path=NodeType. I'm new to WPF, and I found that normally, when I did binding without using this template stuff, I didn't need to specify the predicate 'DataContext', right? Why we need here?
Another thing I found is, I can comment out this.DataContext = this.MemberInfo, and change binding path to Path=MemberInfo.NodeType, the code still works fine. Could anyone explain that for me?
Thanks in advance!
If you dont change the DataContext manuelly, every child automatically has the DataContext of its Parent. So if your Window has f.e. the ViewModel as DataContext all of its Controls have access to the ViewModels Properties through {Binding Path=Property}.
But in case of a ControlTemplate the usual typical flow where DataContext just cascades through from the parent to child doesn’t apply here. So you have to set the DataContext first, either through Property="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataContext.Property}" or DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataContext}" Property="{Binding Path=Property}".
To your second point: It could be, that the ControlTemplate automatically uses the code-behind of its containing Element as DataContext, so you can use the code-behinds properties without setting the DataContext, but I am not 100% sure about this.
I am using WPF having a strange issue with RadListBox SelectedItem databinding, trying to figure out but no luck. Following is my scenario
I am using Telerik Controls (RadListBox, and RadButton)
RadButton is placed inside a ItemsControl, RadListBox and ItemsControl are bind to same ItemsSource.
I am using PRISM and MVVM.
What I want is when I click on button, the same item is selected from RadListBox automatically, (This part working fine).
Problem: As soon as I click on any item of RadListBox and then click back on any button the item selection stops working.
Edit: I tried the same thing with standard WPF ListBox by adding attached behavior for selection changed event and attached property of Command and CommandParameter, it works fine, so it looks like an issue with Telerik RadListBox ?
Now let me come to code.
ViewModel Class
public class MainViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
// Create the OnPropertyChanged method to raise the event
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
public DelegateCommand<object> StudentSelected { get; set; }
public DelegateCommand<object> ButtonPressed { get; set; }
private void OnStudentSelected(object par)
{
//Debugger.Break();
if (handled == false)
{
Student std = par as Student;
if (std != null)
{
SelectedStudent = std;
}
}
handled = false;
}
private void OnButtonPressed(object par)
{
//Debugger.Break();
handled = true;
String std = par as String;
if (std != null)
{
foreach (Student st in _students)
{
if (st.Name.Equals(std))
{
SelectedStudent = st;
break;
}
}
}
}
private Student _selectedstudent;
private bool handled = false;
public MainViewModel()
{
StudentSelected = new DelegateCommand<object>(OnStudentSelected);
ButtonPressed = new DelegateCommand<object>(OnButtonPressed);
}
public Student SelectedStudent
{
get
{
return _selectedstudent;
}
set
{
_selectedstudent = value;
OnPropertyChanged("SelectedStudent");
}
}
private ObservableCollection<Student> _students;
public ObservableCollection<Student> Students
{
get
{
return _students;
}
set
{
_students = value;
OnPropertyChanged("Students");
}
}
}
public class Student
{
public String Name { get; set; }
public String School { get; set; }
}
MainView XAML
<telerik:RadListBox Grid.Column="0" Grid.Row="0" ItemsSource="{Binding Students}" Command="{Binding StudentSelected}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=Self}, Path=SelectedItem}" SelectedItem="{Binding SelectedStudent, Converter={StaticResource DebugConverter}}">
<!-- The above debug converter is just for testing binding, as long as I keep on clicking button the Converter is being called, but the moment I click on RadListBoxItem the Converter is not called anymore, even when I click back on buttons -->
<telerik:RadListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"></TextBlock>
</DataTemplate>
</telerik:RadListBox.ItemTemplate>
</telerik:RadListBox>
<Label Grid.Row="0" Grid.Column="1" Content="{Binding SelectedStudent.Name}"></Label>
<StackPanel Grid.Column="1" Grid.Row="1" Orientation="Horizontal">
<ItemsControl ItemsSource="{Binding Students}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<telerik:RadButton Width="100" Height="70" Content="{Binding Name}" Command="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Window}}, Path=DataContext.ButtonPressed}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Content}">
</telerik:RadButton>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
and finally populating the ViewModel and setting the Datacontext
MainViewModel mvm = new MainViewModel();
ObservableCollection<Student> students = new ObservableCollection<Student>();
students.Add(new Student { Name = "Student 1", School = "Student 1 School" });
students.Add(new Student { Name = "Student 2", School = "Student 2 School" });
students.Add(new Student { Name = "Student 3", School = "Student 3 School" });
mvm.Students = students;
//Bind datacontext
this.DataContext = mvm;
Please give your suggestions and share you expertise from WPF Jargon?
Finally I figured out the issue, I just need to replace the RadListBox SelectedItem binding to TwoWay
<telerik:RadListBox Grid.Column="0" Grid.Row="0" ItemsSource="{Binding Students}" Command="{Binding StudentSelected}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=Self}, Path=SelectedItem}" SelectedItem="{Binding SelectedStudent, Mode,TwoWay, Converter={StaticResource DebugConverter}}">