Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
445 views
in Technique[技术] by (71.8m points)

c# - How can I replace static ObservableCollection so it accesable on all windows in the MVVM way

Atm I got a class(somerandomclasss) with a static ObservableCollection:

public static ObservableCollection<PersonViewModel> thepeoplelist = new ObservableCollection<PersonViewModem>();

However, I am converting my project to MVVM and of course this is not a good way to fill all my itemscontrols(listviews mainly) I got multiple windows that use this source in this way.

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    lsvallthepeople.ItemSource = somerandomclasss.thepeoplelist;
}

The listview displays then all the people with the info. However this isn t the MVVM way I bet, and I haven't found a good way to work without a public static ObservableCollection, however there is a window where you got a listview where you can edit the persons, they get updated in the SQL database and in the PersonViewModel (that got the INotifyPropertyChanged).

If you need any more information feel free to ask ofc :).

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I believe what your are asking is, "What is the best way to share a list of items across multiple views in MVVM?" so I'll answer the question that way.

Let's assume you have a service that provides a way to get the list of people. You called it a "PersonViewModel", but you might be confusing a domain entity with a ViewModel. In MVVM, you have a view which represents the UI control or screen. Then you have a ViewModel which binds to the view and joins the View to the data/domain model. The ViewModel can have a number of public properties that the View will bind to including methods that call services to populate those properties from your data model. In your case, I would have a View + ViewModel and the ViewModel has an ObservableCollection property of class "Person".

The following code is a paraphrase of what it might actually look like. Not everything is implemented.

public class MyViewModel : INotifyPropertyChanged
{
    public ObservableCollection<Person> People { get; set; }

    public MyViewModel()
    {
        this.People = new ObservableCollection<Person>();
        this.LoadPeople();
    }

    private void LoadPeople()
    {
        this.People.Clear();
        // Have your logic here that loads the people collection
    }
}

As far as managing a single list, I recommend caching the people collection in some kind of static class or singleton that is accessible to your view models. Then the LoadPeople method above can just pull from the cache. You can even lazy-load the cache so that it doesn't make the service request until its first access.

internal static class SystemContext
{
    private static ObservableCollection<Person> _people = null;
    public static ObservableCollection<Person> People
    {
        get
        {
            if( _people == null )
            {
                _people = new ObservableCollection<Person>();
                // load the list here from a service or something
            }

            return _people;
        }
    }
}

So in your ViewModel, LoadPeople would then look something like this:

public void LoadPeople()
{
    this.People.Clear();

    foreach( Person person in SystemContext.People )
    {
        this.People.Add( person );
    }
}

Your UI will then look something like this:

<ListBox 
    ItemsSource={Binding Path=People, Mode=OneWay}
    SelectedItem={Binding Path=SelectedPerson, Mode=TwoWay}
    >
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Vertical">
                <TextBlock Text="{Binding Path=PersonName, Mode=OneWay}" />
                <TextBlock Text="{Binding Path=DateOfBirth, Mode=OneWay}" />
                <!-- etc -->
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...