Question

I already have a working ListBox with Items from my local database. Now I wanted to upgrade this to a CollectionViewSource for filtering. After my upgrade the new ListBox with CollectionViewSource shows nothing.

MainPage Code Behind:

    // Data context for the local database
    private BuildingDataContext toDoDB;

    // Define an observable collection property that controls can bind to.
    private ObservableCollection<Building> _buildings;
    public ObservableCollection<Building> BuildingTable
    {
        get
        {
            return _buildings;
        }
        set
        {
            if (_buildings != value)
            {
                _buildings = value;
                NotifyPropertyChanged("BuildingTable");
            }
        }
    }

    public CollectionViewSource Source { get; set; }

    // Konstruktor
    public MainPage()
    {
        InitializeComponent();
        // Connect to the database and instantiate data context.
        toDoDB = new BuildingDataContext(BuildingDataContext.DBConnectionString);

        // Data context and observable collection are children of the main page.
        this.DataContext = this;
    }

    protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
    {
        // Define the query to gather all of the to-do items.
        var toDoItemsInDB = from Building todo in toDoDB.BuildingTable
        select todo;

        // Execute the query and place the results into a collection.
        BuildingTable = new ObservableCollection<Building>(toDoItemsInDB);

        Source = new CollectionViewSource();
        Source.Source = BuildingTable;

        // Call the base method.base.OnNavigatedTo(e);
    }

For that purpose I added the lines:

public CollectionViewSource Source { get; set; }
Source = new CollectionViewSource();
Source.Source = BuildingTable;

I tried as well to put

Source = new CollectionViewSource();
Source.Source = BuildingTable;

in my MainPage Constructor. It doesnt work as well.

My Mainpage.xaml:

        <!--<ListBox x:Name="toDoItemsListBox" ItemsSource="{Binding BuildingTable}" Grid.Row="0" Margin="12, 0, 12, 0" Width="440" SelectionChanged="goToNavigation">-->
        <ListBox x:Name="toDoItemsListBox" ItemsSource="{Binding Source.View}" Grid.Row="0" Margin="12, 0, 12, 0" Width="440" SelectionChanged="goToNavigation">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid HorizontalAlignment="Stretch" Width="440">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="100" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>
                        <TextBlock Name="textBlockShortcut" Text="{Binding Shortcut}" Width="Auto" HorizontalAlignment="Left" Grid.Column="0" Margin="0,0,0,5" FontSize="36" />
                        <TextBlock Name="textBlockName" Text="{Binding BuildingName}" Width="Auto" HorizontalAlignment="Left" Grid.Column="1" Margin="0,0,0,5" FontSize="36" />
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

The first commented line shows the old working listbox without CollectionViewSource. So what am I missing?

EDIT:

    private void goToNavigation(object sender, RoutedEventArgs e)
    {
        // If selected index is -1 (no selection) do nothing
        if (toDoItemsListBox.SelectedIndex == -1)
            return;

        // Navigate to the new page
        PhoneApplicationService.Current.State["SelectedItem"] = toDoItemsListBox.SelectedItem;
        NavigationService.Navigate(new Uri("/NavigationPage.xaml", UriKind.Relative));

        // Reset selected index to -1 (no selection)
        toDoItemsListBox.SelectedIndex = -1;
    }
Was it helpful?

Solution

You would usually create and bind to a CollectionViewSource in XAML:

<UserControl.Resources>
    <CollectionViewSource x:Key="cvs"/>
</UserControl.Resources>
<Grid>
    <ListBox ItemsSource="{Binding Source={StaticResource cvs}}" ...>
        ...
    </ListBox>
</Grid>

and in code-behind just access that CollectionViewSource like this:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    ... 
    var cvs = Resources["cvs"] as CollectionViewSource;
    cvs.Source = BuildingTable;
}

OTHER TIPS

You don't use the CollectionViewSource class directly, you use a CollectionView of the appropriate type.

View = CollectionViewSource.GetDefaultView( myCollection );

and then you bind that directly to your source.

ItemsSource="{Binding View}"

You can and only should use a CollectionViewSource from xaml, because thats its main purpose. From code you should directly create a CollectionView or use the GetDefaultView method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top