tags:

views:

175

answers:

4

Hi, Please see my code below, I want to add data in the roomBlock collection such that for every unique names in Hotelnm, it contains all the records for that particular hotel name. So if my UI first displays hotel name as ABC then the corresponding roomBlock will have all the records from result.ResultSet that has that name in it. How will I do this?

Hotelnm is hashset that contains unique names of hotel. Now I want to display for each name in hashset, a set of data for that particular hotel. For example my result.ResultSet contains records that have multiple times a hotel name. So i want to display once that hotel name and then all the records with that hotel name. The code that I have bolded above doesnot show all the records for a particular hotel, it shows it just once.

+1  A: 
foreach (DomainObject obj in result.ResultSet)
            {
                RoomBlock rmblk = (RoomBlock)obj;

                if (!Hotelnm.Contains(rmblk.HotelName))
                {
                    Hotelnm.Add(rmblk.HotelName);
                    **//roomBlock.Add(new RoomBlockViewModel(rmblk));**
                }

            }

If your records are in result.ResultSet, then your code guarantees that you will see at most one record per hotel.

This is because you wrote if (!Hotelnm.Contains(rmblk.HotelName)) before Hotelnm.Add(rmblk.HotelName). On each subsequent record in the foreach loop, you are guaranteed not to add any rmblk for the same hotel.

Rice Flour Cookies
I know, like you said the UI only displays one record. But how will I display all the records for that particular Hotelnm? what will my code be for it..
developer
The reason I added if (!Hotelnm.Contains(rmblk.HotelName)) code is that I wanted unique hotel names in hashset so my mainlistbox loops through the specific hotels only once, but my other listbox in that mainlistbox binds to roomBlock which I want to have all the records for that particular hotel in result.ResultSet. I know my code wont work, but I do not know what code should I write to make it work in the above way..
developer
A: 

The code you have highlighted should not be inside the conditional. This is not unique data. It needs to be outside the conditional.

foreach (DomainObject obj in result.ResultSet) 
{ 
    RoomBlock rmblk = (RoomBlock)obj; 

    if (!Hotelnm.Contains(rmblk.HotelName)) 
    { 
        Hotelnm.Add(rmblk.HotelName);
    } 

    roomBlock.Add(new RoomBlockViewModel(rmblk)); 


} 
MainListBox.DataContext = Hotelnm; 

EDIT: My assumption is that you have a variable somewhere called roomBlock that is being used to hold this information and that it's linked to Hotelnm. If you're looking to add this in some way to Hotelnm, you'll need to provide some connection to it.

Joel Etherton
Hotelnm is a hashset and roomBlock is an observable collection. I do not know how to link the two, so that for one hotel name in the hashset there is a list of records in roomBlock only with that particular hotel name. The above code that you have shown puts all the records in roomBlock. So I want my mainListbox which is bound to Hotelnm display unique names of hotels and the sublistbox in the mainlistbox as shown in my code above to show only list of hotels with that hotel name(one displayed by the record in hashset)
developer
+1  A: 

You are talking about a master/detail relationship (between controls) and you're code is not doing that. You have created a "master list" of hotel names but you haven't captured the details for each hotel in any data structure (that I can see in your example).

You need to collect the unique names of hotels (and maybe a unique ID) and then create a subsequent data structure that holds the details for all the hotels and then hook up the master control to the detail control so that when you change the index of the master control (ComboBox for example), the detail control (Data grid for example) shows you all of the details for that hotel name.

// link query to get you a list of distinct hotel names
var hotelNames = result.ResultSet.Select(rb => rb.HotelName).Distinct().ToList();

Now you have a distinct list of hotel names and you need to bind that collection to a control. When that control SelectedIndex changes, you need to update the contents of another collection of detail records that are in a different collection and bound to a data grid or some tabular representation.

// list of details passed on a hotelname
// the where clause has a variable that represents the hotel name from the SelectedIndex
// in the master list
var hotelDetails = results.ResultSet.Where(rb.HotelName == hotelNameVariable);

I think this is a start to solving your problem. You really need to step back, try and understand what it is you are trying to do, and break it down into small steps that you can build upon slowly.

Or I could be completely off track. :) I've guessed a little at the intent of your questions and what you are trying to do.

Dave White
+1  A: 

The first thing you need to do is create a SortedDictionary<string, RoomBlockViewModel>, whose key is the hotel name. This can be done readily like this:

Dictionary<string, List<RoomBlockViewModel>> hotelRooms = result.resultSet
    .Cast<RoomBlock>()
    .Select(x => new RoomBlockViewModel(x))
    .GroupBy(x => x.HotelName)
    .ToDictionary(x => x.Key, x => x.ToList()); 

Hotels.DataContext = new SortedDictionary<string, List<RoomBlockViewModel>>(hotelRooms);

This assumes that the RoomBlockViewModel exposes a HotelName property so that you can group by it, and that the hotel names are unique. Hotels, in this code, is the ListBox containing the hotels.

When you bind to a dictionary in WPF, you're really binding to an IEnumerable<KeyValuePair<TKey, TValue>> - that is, every object in the data source has a Key and a Value property, which in this case are of type string and List<RoomBlockViewModel>.

So the list of hotels has this dictionary as its data context, and uses an ItemTemplate to present the Key (i.e. the hotel name). And the list of room blocks has its ItemsSource bound to SelectedItem.Value on the Hotels list box - because Value contains a List<RoomBlockViewModel>.

<DockPanel>
    <ListBox x:Name="Hotels"
                Margin="5"
                Background="Lavender"
                DockPanel.Dock="Top"
                ItemsSource="{Binding}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Path=Key}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

    <ListBox Margin="5"
                Background="AliceBlue"
                ItemsSource="{Binding ElementName=Hotels, Path=SelectedItem.Value}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Info}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

</DockPanel>
Robert Rossney
Hi,thanks for the answer. Here you have used Linq query to arrange the data in the dictionary. Is it possible without using Linq query?
developer
Of course. There's nothing you can do in Linq that you can't do by writing a `foreach` loop with a lot of code in it.
Robert Rossney