views:

753

answers:

1

Hi All,

This is a long one . I am adding code so that you can see what I am trying to do. Let me know if anything is not clear

I am trying to get selected items from nested listbox in multiselct mode . Here is code ( removed lot of unwanted stuff)

public class Item
{
    public string Name { get; set; }

    public IList<Item> SubItems { get; set; } // 

    public bool IsSelected { get; set; }
}
//Chicken Fried Chicken 
//A hearty boneless chicken breast, lightly breaded in our special seasonings and 
//golden fried. Served with garlic mashed potatoes, country gravy and seasonal vegetables
// from Applebees

//Item - Chicken Fried Chicken 
//SubItem- mashed potatoes
//SubItem- country gravy
//SubItem- seasonal vegetables
//SubItem- Fries
//SubItem- Sauted vegetables
//SubItem- House Salad

public class ItemViewModel : INotifyPropertyChanged, IItemViewModel
{


    ObservableCollection<Item> selectedData = new ObservableCollection<Item>();

    private ObservableCollection<Item> todaysItems;
    public ObservableCollection<Item> TodaysItems
    {
        get { return todaysItems; }
        private set
        {
            if (todaysItems != value)
            {
                todaysItems = value;
                PropertyChanged(this, new PropertyChangedEventArgs("todaysItems"));
            }
        }
    }



    public ItemViewModel(IItemView itemView)
    {
        this.View = itemView;
        this.View.Model = this;

        List<Item> items = service.GetAllTestItems();
        TodaysItems = new ObservableCollection<Item>(items);

        selectedData.CollectionChanged += (sender, e) => UpdateSummary();
    }



    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged = delegate { };
    private void NotifyPropertyChanged(string propertyName)
    {
        var handler = this.PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    #endregion


    // How to get Selected Items from ListBox

    public ObservableCollection<Item> SelectedData
    {
        get { return selectedData; }
        set
        {
            selectedData = value;
        }
    }


    private void UpdateSummary()
    {
        // here I can get selected data , I can find which Item is selected and then update its SubItems IsSelected (CLR) Property
        // but something is not right here
    }
}

XAML

<UserControl x:Class="ItemView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:prism="clr-namespace:Microsoft.Practices.Composite.Presentation.Commands;assembly=Microsoft.Practices.Composite.Presentation"
             xmlns:ZCom="clr-namespace:MyProj.Infrastructure;assembly=Infrastructure">

    <Grid  >
        <ListBox ItemsSource="{Binding TodaysItems}">
            <ListBox.ItemTemplate>
                <DataTemplate >
                    <Border BorderThickness="1,1,1,1" CornerRadius="2,2,2,2" BorderBrush="Black">
                        <Grid   MinHeight="50" Width="150" Height="Auto" Margin="0,0,0,0">
                            <Grid.RowDefinitions>
                                <RowDefinition />
                                <RowDefinition/>
                                <RowDefinition />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="150"/>
                                <ColumnDefinition Width="0"/>
                            </Grid.ColumnDefinitions>
                            <TextBlock Margin="4,4,2,2" Grid.Row="0"  Width="Auto" TextWrapping="Wrap" Text="{Binding Path=Name}"  />
                            <Grid Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" >
                                <Grid.Style>
                                    <Style>
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding Path=IsSelected, RelativeSource=
                                                                    {RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}}
                                            }" Value="false">
                                                <Setter Property="Grid.Visibility" Value="Collapsed"/>
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </Grid.Style>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="35"/>
                                    <RowDefinition Height="*"/>
                                </Grid.RowDefinitions>
                                <TextBlock Margin="2,4,2,2"  Grid.Row="0" Width="Auto" FontSize="10" FontStyle="Italic"  TextWrapping="Wrap"  Text="{Binding Path=Note}"/>

                                <ListBox Style="{DynamicResource MyStyle}" Grid.Row="1"  ItemsSource="{Binding Path=Modifiers}"  SelectionMode="Multiple"
                                         ZCom:ListBoxHelper.SelectedItems="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.SelectedData}">
                                    <ListBox.ItemTemplate>
                                        <DataTemplate >
                                            <TextBlock Margin="2,2,2,2"  TextWrapping="Wrap" Text="{Binding Path=Name}"  />
                                        </DataTemplate>

                                    </ListBox.ItemTemplate>
                                </ListBox>
                            </Grid>

                        </Grid>
                    </Border>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</UserControl>

I am using ListBoxHelper ( in Infrastructure) from http://marlongrech.wordpress.com/2009/06/02/sync-multi-select-listbox-with-viewmodel/

I get the view with Item and SubItems.

1) what is better way to set IsSelected Property of SubItems from nested ListBox

I will add a command which will store selected Item to Database once double clicked. SubItems will be stored as child record based on its IsSelected value.

2) Is there a way to make SubItems property of c# class observable . I would not want to change by adding Observable to the object as it will be in another assembly and may be used by other applications.

Edit 1: Found somewhat helpful question

WPF Databinding to composite class patterns

But again for this I will have to inherit from INotifyPropertyChanged.

Edit 2: Let me see if I can explain better- ListBox1 is Single select Mode and parent & ListBox 2 is multiselect. ListBox1 is binded (item source) to property which returns observablecollection. ListBox2 is binded to a Property in Item Class (Item.SubItems) which returns IList. Item Class has IsSelected Property.I want to be able to select subitems which should set IsSelected Property for the subItems to true. Knowing that there is no INotifyPropertyChanged inheritance in Item Class how can I achieve this. I assume that unless subitems come under some observable collection any changes will not be notified back to source. Using the selectedData property I can update the subitems by finding parent Item but then to update the view I will have to firePropertChanged for "items" which involves all items and subitems. I want only subitems change to be notified back by binding mechanism. Sorry if I am still not clear.

Edit 3:

I Guess there is no way but to implement INotifyPropertyChanged on Item class. Other way would be to implemnt a viewmodel which is very specific to needs of view but this will add up lot of code.

A: 

It's a little confusing what your overall goal here is.

If you're merely trying to get the selected items from a nested ListBox, Have you tried giving your ListBox an x:Name and exposing your SelectedItems via a property in your UserControl (ItemView) class?

public IList SelectedItems
{
  get { return nestedListBox.SelectedItems; }
}
Will Eddins
@Guard- Please see edit 2. I tried to write it as comment but it became too long
TheMar