David B
David B

Reputation: 929

SelectedItem issue in WPF ListBoxItem MVVM

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

Answers (2)

RoelF
RoelF

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: Screenshot Visual Studio while break on property setter

Upvotes: 3

Asha
Asha

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

Related Questions