views:

176

answers:

2

I have a listbox that simply binds to a collection. The collection has a child collection (StepDatas). I would like to bind to a count of the child collection but with a WHERE statement. I can bind to ChildCollection.Count but get lost when needing to add the lambda expression. Here's the XAML:

<ListBox Height="Auto" Style="{StaticResource ListBoxStyle1}" Margin="4,46,4,4" x:Name="lstLeftNavigation" Background="{x:Null}" SelectionChanged="lstLeftNavigation_SelectionChanged">
<ListBox.ItemTemplate>
    <DataTemplate>
  <Grid Width="180" Margin="2,2,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" d:LayoutOverrides="Width" MinHeight="36">
   <TextBlock Text="{Binding StepNm}" x:Name="tbStepNm" Margin="10,0,34,0" TextWrapping="Wrap" FontFamily="Portable User Interface" Foreground="White" FontSize="10" FontWeight="Bold" VerticalAlignment="Center"/>
   <Image Height="37" HorizontalAlignment="Right" Margin="0" VerticalAlignment="Center"  Width="37" Source="Images/imgIcoChecked.png" Stretch="Fill"/>
  </Grid>
    </DataTemplate>
</ListBox.ItemTemplate>

The above works to bind to the count of the child collection. However I wish to show a count of the child collection where a certain condition is met. In this specific case, the child collection has a completed property (bool). So...I want to show the count StepDatas.Where(x => x.Completed == true).Count.

Is this in any way possible? Thanks for any help!

+1  A: 

The short answer to the subject question is: no.

The sensible answer is: Ensure the Count you need is made available a property of the data model. E.g., ensure the type exposed by StepDatas has a Count property.

However you do qualify this with "in any way possible?". It is possible to bind to the ListItem data context and using some value converter madness to execute your lambda. However to keep things simple you need to create a converter specifically for your lambda. Here is what the converter code would look like:-

 public class CountCompletedStepDatas : IValueConverter
 {

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
      YourItemsType item = (YourItemsType)value;
      return item.StepDatas.Were(x => x.Completed == true).Count().ToString(culture);
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
      throw new NotImplementedException();
    }
  }

You would the make an instance of this converter avaiable in a Resources property in the XAML, say of convenience in the UserControl:-

<UserControl x:Class="YourNameSpace.ThisControlName"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:local="clr-namespace:YourNameSpace;assembly=YourAssemblyName">
  <UserControl.Resources>
    <local:CountCompletedStepDatas x:Key="Counter" />
  </UserContro.Resources>

Now in your binding:-

 <TextBlock Text="{Binding Converter={StaticResource Counter} }" ... >
AnthonyWJones
A: 

Thanks for the response. After submitting the question, I wrote a converter class to do what you ended up suggesting but discovered that the count property will not cause a rebind when the data changes. This will force a situation where we will have to manually update the binding when changes are made. Getting a reference of the image object inside the listbox in order to update the target is unforntunately a pain in the arse!

Ultimately, I just added a new field to the datasource and bound the image directly to it like you suggested. Much cleaner.

Thanks for the suggestions! Doug

Doug Lott
should be a comment in the answer that you should accept
Rob Fonseca-Ensor