开发者

Help with C# logic

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 fo开发者_开发百科r 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.


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>


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.


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜