This project is read-only.

Binding using ExpressionObserver.Execute

Dec 9, 2009 at 9:44 PM

Thomas

I have an observablecollection of type Customer (Name, State, Income, Expense, ...). I am attempting to bind a listbox to a view grouped by State and display the income and expense as an aggregate around it.

I used the ExpressionObserver to achieve the following.

public IEnumerable<Customer> Grouped
        {
            get
            {
             return ExpressionObserver.Execute(
                        custOrdersList,
                            n => n.Select(p => p.State).Distinct()
                    ).Cascade();
            }
        }
<font size="2" color="#0000ff"><font size="2" color="#0000ff">

<

</font></font>ListBox Name="filtrMon" SelectionMode="Extended" ItemsSource="{Binding Grouped.Value}">
<font size="2" color="#0000ff">

 

</font>ListBox Name="filtrMon" SelectionMode="Extended" ItemsSource="{Binding Grouped.Value}">

ListBox Name="filtrMon" SelectionMode="Extended" ItemsSource="{Binding Grouped.Value}">

			<ListBox.ItemTemplate>
                                <DataTemplate>
                                    <StackPanel>                                        <font size="2" color="#0000ff"><font size="2" color="#0000ff">

<

</font></font>
<font size="2" color="#0000ff">

 

</font>

TextBlock Text="State" FontSize="9" ></TextBlock>

<TextBlock Text="Income" FontSize="9" ></TextBlock>

<TextBlock Text="Expense" FontSize="9" ></TextBlock>

</StackPanel> </DataTemplate> </ListBox.ItemTemplate>

<ListBox>

The snippet above does not bind to the aggregates. 
Any help on this will be highly appreciated.
Thanks
Vinay 
Dec 10, 2009 at 7:06 AM

Hi Vinay,

It looks you are trying to bind to a Value property of Grouped. But Grouped is of type IEnumerable<Customer> and does not have a Value property. I think you should bind to Grouped directly and not to Grouped.Value.

Regs,

Thomas.

Dec 10, 2009 at 5:13 PM

Thomas

Thanks for the reply. On the same line is there a way to return IEnumerable<Customer> by grouping the list by a property say State and Aggregating Expense and Income.

public IEnumerable StateGrouped
        {
            get
            {
                return ExpressionObserver.Execute(custOrdersList, t =>
                        from q in t.OfType().ToList()
                         group new{ 
                             q.Expense, q.Income, q.State
                         } by q.Moniker
                       ).Cascade();
            }
        }

I am trying to return an IEnumerable grouped by a property State with Aggregated values for Income and Expense.

In essence this is what I am trying to observer

var q = _selectedCustomers.OfType().GroupBy(x => x.State)
            .Select(x => new CustomerSummary
            {
                State = x.First().State,
                Expense = x.Sum(p => p.Expense),
                Income = x.Sum(p => p.Income),
            }).OrderByDescending(c => c.Expense);
q here returns a list grouped by state with aggregated expense and income.
Again thanks alot for your help
Vinay
Dec 10, 2009 at 6:42 PM

Hi Vinay,

If you have a working expression that returns the desired result then just feed that expression the ExpressionObserver.Execute method and you should get a live version.

So if you latter expression works (probably need to specify a type in your call to OfType()):

ExpressionObserver.Execute(
    _selectedCustomers,
    selectedCustomers =>
        selectedCustomers.OfType().GroupBy(x => x.State)
            .Select(x => new CustomerSummary
            {
                State = x.First().State,
                Expense = x.Sum(p => p.Expense),
                Income = x.Sum(p => p.Income),
            }).OrderByDescending(c => c.Expense)
).Cascade(); 

If you use Silverlight you unfortunately can't use anonymous types in observable expressions. This is due to a lack of reflection permissions in a Silverlight runtime context.

Regs,

Thomas.

Dec 11, 2009 at 5:51 PM
Edited Dec 11, 2009 at 5:58 PM

Hi Thomas using the following I am able to group based on a particular property. However, when there is a change in the collection I get a Catastrophic error

public IEnumerable StateGrouped
        {
            get
            {
                return ExpressionObserver.Execute(custOrdersList, t =>
                        t.OfType().ToList().GroupBy(x => x.State)
                        .Select(x => new StateSummary
                        {
                            State = x.First().State,
                            Expense = x.Sum(p => p.Expense),
                            TotalIncome = x.Sum(p => p.Income),
                        }).OrderByDescending(c => c.Expense)
                       ).Cascade();
            }
        }
I bind the Above to a usercontrol which contains a listbox. But when i edit an item in the original list (custOrdersList) 
i get a catastrophic error. The list is also binded to a datagrid via PagedCollectionView. 
Thanks
Vinay
Dec 12, 2009 at 1:45 PM

Hi Vinay,

The most likely cause would be that your StateSummary class is not 'well-behaved'. If you would create two instances (a and b) of StateSummary with the same arguments that it should be so that a.Equals(b) == true. If StateSummary would be a struct then this is automatically the case but if it is a class then you need to override the Equals() and GetHascode() methods to make sure that a.Equals(b) == true.

Regs,

Thomas.