当我谈到MVVM时,我仍然认为自己是初学者,而我在TabControl中遇到绑定问题.我的应用程序允许用户创建国家和州,输入一些信息,然后将它们保存到数据库中.以下是我的应用程序结构的描述:
基本ViewModel / View称为ApplicationViewModel / ApplicationView. ApplicationViewModel有一个名为Tabs的ObservableCollection,它包含一个AllNationsViewModel和一个AllStatesViewModel.此Tabs属性绑定到ApplicationView中的TabControl的ItemsSource.
AllNationsViewModel / AllNationsView用于显示用户输入的所有国家/地区.它还允许用户创建新的国家并选择一个特定的国家进行更仔细的检查. AllStatesViewModel / AllStatesView对状态执行相同操作.
最后,我有NationViewModel / NationsView处理特定国家;此处还有StateViewModel / StateView对状态执行相同操作.
对于一个国家,您现在只能输入一个名称,但对于一个州,您可以输入一个名称以及它所属的国家.使用ComboBox选择国家,其中所有国家选项卡中创建的国家都会显示出来.
我使用一个名为DataFacade的静态类作为我的数据存储的接口.可以使用此界面添加,删除和检索国家/州的列表;它还会在添加或删除某些内容时触发事件.
我遇到的问题是,当AllStatesViewModel(CurrentStateViewModel属性)中选择了一个状态,然后我转到NATIONAL选项卡,然后返回状态选项卡,当前选择的状态已失去其国家.所有其他州仍然很难.
我将尝试显示下面的相关代码(我从一些方法中删除了不相关的代码):
州级:
class State
{
public string Name { get; set; }
public Nation Nation { get; set; }
}
ApplicationView中的TabControl:
<TabControl ItemsSource="{Binding Tabs}" Margin="6">
<TabControl.ItemTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding DisplayName}" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding }" />
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
当用户创建国家时,将触发AllNationsViewModel的AddCommand:
private void Add(NationViewModel vm)
{
DataFacade.AddNation(vm.Nation);
}
当一个国家被添加到数据存储时,AllStatesViewModel会收到通知:
private void OnDataStoreNationsChanged(object sender, DataFacadeEventArgs e)
{
Nations.Add(new NationViewModel(e.Context as Nation));
}
上面的Nations属性是NationViewModels的ObservableCollection.现在,StateView中的ComboBox使用此属性来填充其项目,以便在创建/编辑状态时可以选择国家/地区:
<ComboBox Grid.Row="1" Grid.Column="1" SelectedValue="{Binding Nation}" SelectedValuePath="Nation" ItemsSource="{Binding DataContext.Nations, RelativeSource={RelativeSource AncestorType={x:Type local:AllStatesView}}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
我认为这个问题与上面的绑定有关.因为如果我没有绑定到AllStatesViewModel中的Nations属性,而是绑定到ApplicationViewModel中的临时属性,一切正常.当我转到另一个选项卡时,TabControl是否会抛弃AllStatesView,因为上面的绑定将我的StateViewModel的Nation属性设置为null?当我调试时,我看到退出状态选项卡时我得到一个null.
像我这样的初学者怎么会解决这种情况呢?我发现我的临时解决方案相当丑陋.我不完全确定如何处理数据存储访问,因为我发现的所有MVVM示例都没有关注这一部分.
编辑:按要求添加一些图片:
Atm我只有最简单的测试GUI设置:
在这里你看到AllNationsView,atm NationView只是“Name”TextBlock和顶部的TextBox.
这是AllStatesView,顶部是当前选择的状态(使用StateView显示).你现在看到美国被选为蒙大拿州的国家,如果我进入国家选项卡然后回到州选项卡,蒙大拿州的国家现在是空白的.如果我选择佛罗里达州,它仍然以美国为国家.
最佳答案 WPF仅将活动选项卡的UI保留在内存中.当您更改选项卡时,将销毁UI并创建新选项卡的UI并进行回弹.
您可以通过几种方式解决问题.您可以使用存储库模式存储和访问与视图模型分开的数据源.基本上,外部对象保存您的数据源,例如州和国家列表.这样,当活动选项卡更改时,它们不会被销毁.
另一个选项是将数据源存储在ApplicationViewModel上,并通过对每个单独选项卡视图模型上的ApplicationViewModel的引用来访问它们.您不必在任何地方使用RelativeSource绑定.