Offer
Offer

Reputation: 630

How to fire command when page is shown

This is my scenario.

I have a MainWindow with a frame. This frame allows me to navigate from Page1 to Page2 to Page3 (in any order).

What I need is; When each page is displayed, I need a command to be fired

For instance:

My 3 pages all have DataGrids.

mc:Ignorable="d"
  Title="Page1">

<DataGrid DataContext="{Binding Source={x:Static VM:ViewModel.Instance}}"
          ItemsSource="{Binding CustomerCollection, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
          RowDetailsVisibilityMode="VisibleWhenSelected"
          AutoGenerateColumns="True">

</DataGrid>

These DataGrids are bound to the same 'Customer' ObservableCollection in the same (static) ViewModel.

    public ObservableCollection<customer> CustomerCollection
    {
        get
        {
            return _customercollection;
        }
        set
        {
            _customercollection = value;
            OnPropertyChanged("CustomerCollection");
        }
    }

This means that at any given point in time, each page shows the same Customer information.

Now I want Page1 to show active Customers, Page2 to show suspended Customers, and Page3 to show resigned Customers.

I need to fire different query in the ViewModel for each page. Each query is specific to page.

But how do I get this query to fire automatically as I navigate from page to page?

The idea here is to limit how much memory is in use when the application runs by recycling the same ObservableCollections.

Upvotes: 1

Views: 138

Answers (3)

Justin CI
Justin CI

Reputation: 2741

I think you can bind a command to loaded event to each page and pass a command parameter ,depending upon than you can select your observable collection.

<Window x:Class="V_Parcel.SplashPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:CommandClass="clr-namespace:V_Parcel"
        xmlns:prop="clr-namespace:V_Parcel.Properties"
        xmlns:vm="clr-namespace:V_Parcel"     
        xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
       >
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">
            <i:InvokeCommandAction Command="{Binding StartButton}" CommandParameter="1" />
        </i:EventTrigger>
    </i:Interaction.Triggers>

Upvotes: 3

Huusom
Huusom

Reputation: 5912

You can use the events on NavigationService to setup your viewmodel. More - and better - information on NavigationService here: http://paulstovell.com/blog/wpf-navigation

You could also try to put a Converter on each ItemSource that filters your collection.

Upvotes: 0

Dennis
Dennis

Reputation: 37770

View model is a thing, that prepares data to be easily displayed in a view.
You need a filtered data - so, do the filtering somewhere in view model.

One way is to hide CustomerCollection and make collection views in the same view model (but it would be better to hold a separate view model per page):

public class ViewModel
{
    private ObservableCollection<Customer> _customercollection;

    private void LoadCustomers()
    {
        _customercollection = // load customers somehow;
        ActiveCustomers = new ListCollectionView(_customercollection)
        {
            Filter = c => ((Customer)c).IsActive
        };
        OnPropertyChanged("ActiveCustomers");

        // almost the same code for SuspendedCustomers and ResignedCustomers
    }

    public ICollectionView ActiveCustomers { get; private set; }
    private ICollectionView SuspendedCustomers { get; private set; }
    private ICollectionView ResignedCustomers { get; private set; }

    // rest of code
}

XAML:

<DataGrid ItemsSource="{Binding ActiveCustomers}"/>

Note, that you can make these properties using lazy initialization (thus, create appropriate collection view on demand).

Upvotes: 2

Related Questions