Reputation: 929
I am new to WPF and attempting to design following the MVVM design pattern. My issue is I cannot get the selected Item when the user selects this item in the ListBox. I appreciate your help, Thanks. I have stripped out some of the code in the methods that is not needed.
Sorry I should add the listbox named: lbPositionAttributeMasters is the one that is not working.
XAML:
<Grid>
<StackPanel />
<ListBox x:Name="lbPositionAttributeMasters" ItemsSource="{Binding PositionAttributeMasterCollection}" SelectedItem="{Binding SelectedAttributeMaster, Mode=TwoWay}" Margin="0,10,280,10">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding PositionAttributeMasterDescription}"></TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox x:Name="lbPositionAttributesForMaster" ItemsSource="{Binding PositionAttributesCollection}" Margin="270,10,10,10">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding PositionAttributeDescription}"></TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
ViewModel:
public event PropertyChangedEventHandler PropertyChanged;
private ObservableCollection<PositionAttributes> _positionAttributeMasterCollection;
private ObservableCollection<PositionAttributes> _positionAttributeCollection;
private IList<PositionAttributes> _positionAttributeMasterDescription;
private IList<PositionAttributes> _positionAttributeDescription;
private PositionAttributes _selectedAttributeMaster;
public PositionAttributesViewModel()
{
}
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public ObservableCollection<PositionAttributes> PositionAttributeMasterCollection
{
get { return _positionAttributeMasterCollection;}
set
{
_positionAttributeMasterCollection = value;
OnPropertyChanged("PositionAttributeMasterCollection");
}
}
public ObservableCollection<PositionAttributes> PositionAttributeCollection
{
get { return _positionAttributeCollection; }
set
{
_positionAttributeCollection = value;
OnPropertyChanged("PositionAttributeCollection");
}
}
public IList<PositionAttributes> PositionAttributeMasterDescription
{
get { return _positionAttributeMasterDescription; }
set
{
_positionAttributeMasterDescription = value;
OnPropertyChanged("PositionAttributeMasterDescription");
}
}
public PositionAttributes SelectedAttributeMaster
{
get{ return _selectedAttributeMaster; }
set
{
_selectedAttributeMaster = value;
OnPropertyChanged("SelectedAttributeMaster");
}
}
public IList<PositionAttributes> PositionAttributeDescription
{
get { return _positionAttributeDescription; }
set
{
_positionAttributeDescription = value;
OnPropertyChanged("PositionAttributeDescription");
}
}
/// <summary>
/// Gets all Attribute Masters and Sub Attribute Masters
/// </summary>
/// <returns></returns>
public ObservableCollection<PositionAttributes> GetPositionAttributeMasters()
{
foreach(var item in listofpositionAttributes)//Add to observable collection
{
PositionAttributeMasterCollection.Add(item);
}
return PositionAttributeMasterCollection;
}
foreach (var item in positionAttributesInMaster)//Add to observable collection
{
PositionAttributeCollection.Add(item);
}
}
return PositionAttributeCollection;
}
}
Upvotes: 2
Views: 520
Reputation: 7573
The code you provided is working as expected. What you describe in the comments, is that during debugging you see {ClientRatesWPF.Model.PositionAttributes}
as a value being set to SelectedAttributeMaster
.
This is completely correct, because the debugger doesn't know how to show you anything more meaningfull. You can do two things:
1) Apply the DebuggerDisplay
attribute to your class:
[DebuggerDisplay("Description = {PositionAttributeMasterDescription}")]
public class PositionAttributes
{
public string PositionAttributeMasterDescription { get; set; }
}
2) Use the Visual Studio debugger to show you additional information:
Upvotes: 3
Reputation: 25
Step 1. Add a relay command in your viewmodel
/// <summary>
/// Command which is fired when a list view item is selected in the main window
/// </summary>
public RelayCommand SelectionChangedCmd { get; private set; }
/// <summary>
/// The listview item selected from the collection.
/// </summary>
public Feature SelectedAttributedMaster { get; set; }
In the constructor of your viewmodel:
public PositionAttributesViewModel()
{
PositionAttributeMasterCollection = new
ObservableCollection<PositionAttributes >();
SelectionChangedCmd = new RelayCommand(() =>
PositionAttributesSelectionChanged(), () => true);
}
//implement what you want to do on selection
private void PositionAttributesSelectionChanged()
{
if(PositionAttributeMasterCollection !=null &&
SelectedAttributedMaster !=null)
{
PositionAttributes feature = SelectedAttributedMaster as
PositionAttributes
//Update the window whenever we select a new feature.
Dispatcher.CurrentDispatcher.DynamicInvoke(delegate()
{
//further implementation
});
}
}
In your XAML add the references and rest of the code.
<Window x:Class="Something.MainWindow"
xmlns:i="clr-namespace:System.Windows.Interactivity; assembly=System.Windows.Interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4">
<ListBox x:Name="lbPositionAttributeMasters" ItemsSource="{Binding PositionAttributeMasterCollection}" SelectedItem="{Binding SelectedAttributeMaster}" Margin="0,10,280,10">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding PositionAttributeMasterDescription}"></TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding SelectionChangedCmd}"
CommandParameter="{Binding}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBox>
Upvotes: 0