c#MVVM每次View访问时都会重置ViewModel数据

时间:2017-09-27 12:26:05

标签: c# wpf xaml mvvm viewmodel

我有一个简单的2 x View + ViewModel程序,它在ViewModel之间共享一些数据,例如 Members ObservableCollection 。我通过父 MainViewModel 执行此操作。但是,每次访问任一视图(通过按钮)时,它都会“刷新”数据,并且似乎重新生成成员ObservableCollection 。两个视图都可以访问Members ObservableCollection,但数据不同。每次访问任何一个视图时,似乎都会创建一个新的“MainViewModel”......?

我的程序逻辑有错吗?我正在尝试创建一个父ViewModel,它允许Child ViewModel / Views共享相同的DataCollections。我不太确定在哪里为子视图设置DataContext ...

感谢您的帮助!

的App.xaml

<Application x:Class="CLM_Scheduler.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-namespace:CLM_Scheduler"
         StartupUri="Views\MainWindow.xaml">
<Application.Resources>
</Application.Resources>

MainWindow.xaml

<Window.DataContext>
    <local1:MainViewModel />
</Window.DataContext>

<Window.Resources>
    <DataTemplate DataType="{x:Type local1:MembersViewModel}">
          <local:MembersView/> 
    </DataTemplate> 
    <DataTemplate DataType="{x:Type local1:WeeksViewModel}">
            <local:WeeksView/> 
    </DataTemplate>

</Window.Resources>

<Grid>
    <DockPanel LastChildFill="True">
        <StackPanel x:Name="navigation" DockPanel.Dock="Left">
            <Button Content="Members" Command="{Binding SelectMembersView}"></Button>
            <Button Content="Schedule" Command="{Binding SelectWeeksView}"></Button>
        </StackPanel>
        <ContentControl x:Name="Pages" DockPanel.Dock="Right" Content="{Binding SelectedViewModel}" />
    </DockPanel>
</Grid>

MainViewModel.cs

class MainViewModel : ObservableObject
{
    private MembersViewModel membersViewModel;
    private WeeksViewModel weeksViewModel;

    public MainViewModel()
    {
        membersViewModel = new MembersViewModel();
        weeksViewModel = new WeeksViewModel();
    }

    public MembersViewModel MembersViewModel
    {
        get { return membersViewModel; }
        set { membersViewModel = value; RaisePropertyChanged("MembersViewModel"); }
    }

    public WeeksViewModel WeeksViewModel
    {
        get { return weeksViewModel; }
        set { weeksViewModel = value; RaisePropertyChanged("WeeksViewModel"); }
    }

    private object selectedViewModel;
    public object SelectedViewModel
    {
        get { return selectedViewModel; }
        set { selectedViewModel = value; RaisePropertyChanged("SelectedViewModel");  }
    }

    public ICommand SelectMembersView { get { return new RelayCommand(SelectMembersViewExecute, CanSelectMembersViewExecute); } }
    void SelectMembersViewExecute()
    {
        SelectedViewModel = MembersViewModel;
    }
    bool CanSelectMembersViewExecute()   {        return true;    }

    public ICommand SelectWeeksView { get { return new RelayCommand(SelectWeeksViewExecute, CanSelectWeeksViewExecute); } }
    void SelectWeeksViewExecute()
    {
        SelectedViewModel = WeeksViewModel;
    }
    bool CanSelectWeeksViewExecute() { return true; }
 }

MembersViewModel.cs

class MembersViewModel :  ObservableObject
{
        private Member _SelectedMember;

        ObservableCollection<Member> _members = new ObservableCollection<Member>();

        public ObservableCollection<Member> Members
        {
            get{ return _members;}
            set
            {
                _members = value;
                RaisePropertyChanged("Members");
            }
        }

        public Member SelectedMember
        {
            get { return _SelectedMember; }
            set { _SelectedMember = value; }
        }

        public MembersViewModel()
        {
            for (int i = 0; i < 3; ++i)
            {
            _members.Add(new Member(_database.GetRandomFirstName, _database.GetRandomLastName));
            }
        }

        void AddMemberExecute()
        {
            if (_members == null)
                return;
        _members.Add(new Member(_database.GetRandomFirstName, _database.GetRandomLastName));
        }

        bool CanAddMemberExecute()  {return true;}
        public ICommand AddMember { get { return new RelayCommand(AddMemberExecute, CanAddMemberExecute); } }
}

Members.xaml

<UserControl.DataContext>
    <local2:MainViewModel />
</UserControl.DataContext>
<Grid>
    <Button Grid.Column="0" Grid.Row="1" Content="Add Member" Command="{Binding MembersViewModel.AddMember}" />
    <DataGrid Grid.Column="1" Grid.Row="3" ItemsSource="{Binding MembersViewModel.Members}" SelectedItem="{Binding SelectedMember, Mode=TwoWay}" >
    </DataGrid>
</Grid>
</UserControl>

Weeks.xaml

<UserControl.DataContext>
    <local1:MainViewModel />
</UserControl.DataContext>
<Grid>
    <Button Grid.Column="0" Grid.Row="1" Content="Add Member" Command="{Binding MembersViewModel.AddMember}" />
    <DataGrid Grid.Column="1" Grid.Row="3" ItemsSource="{Binding MembersViewModel.Members}" SelectedItem="{Binding SelectedMember, Mode=TwoWay}" />
</Grid>

1 个答案:

答案 0 :(得分:1)

视图只能有一个DataContext(视图模型)。每次创建视图时,这会创建一个新的MainViewModel

<UserControl.DataContext>
    <local1:MainViewModel />
</UserControl.DataContext>

如果你想继承DataContext的{​​{1}},你可以像这样绑定它:

MainWindow

你也可以像<UserControl ... DataContext="{Binding DataContext, RelativeSource={RelativeSource AncestorType=Window}}"> 一样绑定到MainWindowViewModel的任何属性(不设置UserControl的{​​{1}}):

DataContext
相关问题