我有UserControl
ParentView ,其中包含DataGrid
和catel:TabControl
,其中每个TabItem
都很小UserControl
其 ViewModel 是BaseTabViewModel的子类。
此BaseTabViewModel
包含自定义类的ObservableCollection
,其属性将生成DataGrid
的列。
由于我的所有标签只有一个DataGrid,如何自动填充选定标签的viewmodel的ObservableCollection?
现在,我只是卸载标签(LoadTabItems="SingleUnloadOthers"
),并且由于每个标签的viewmodel在实例化时重新生成其集合,我使用InterestedIn和OnViewModelPropertyChanged来获取它;然而,这种卸载行为并不完全可靠,而且我经常发现自己的DataGrid仍然由前一个标签填充,而不是在更改标签时进行清理。
要注意,它被清理的事实并不是理想的行为,我现在别无选择。让每个标签保持加载是我的目标。
我知道继承在视图模型方面非常不受欢迎,但老实说,我无法想到更好的方法。
ParentView
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<catel:TabControl LoadTabItems="SingleUnloadOthers">
<TabItem Header="FIRST">
<local:FirstView/>
</TabItem>
<TabItem Header="SECOND">
<local:SecondView/>
</TabItem>
<TabItem Header="THIRD">
<local:ThirdView/>
</TabItem>
<TabItem Header="FOURTH">
<local:FourthView/>
</TabItem>
</catel:TabControl>
<DataGrid Grid.Row="1" IsReadOnly="True" ItemsSource="{Binding Fields}"/>
</Grid>
ParentViewModel
[InterestedIn(typeof(FirstViewModel))]
[InterestedIn(typeof(SecondViewModel))]
[InterestedIn(typeof(ThirdViewModel))]
[InterestedIn(typeof(FourthViewModel))]
public class ParentViewModel : ViewModelBase
{
public ObservableCollection<Field> Fields
{
get { return GetValue<ObservableCollection<Field>>(FieldsProperty); }
set { SetValue(FieldsProperty, value); }
}
public static readonly PropertyData FieldsProperty = RegisterProperty("Fields", typeof(ObservableCollection<Field>));
protected override void OnViewModelPropertyChanged(IViewModel viewModel, string propertyName)
{
if (propertyName.Equals("Fields"))
{
BaseParserViewModel p = viewModel as BaseParserViewModel;
Fields = p != null ?? p.Fields;
}
base.OnViewModelPropertyChanged(viewModel, propertyName);
}
}
BaseTabViewModel
public abstract class BaseTabViewModel : ViewModelBase
{
protected BaseParserViewModel()
{
Fields = new ObservableCollection<Field>();
}
public ObservableCollection<Field> Fields
{
get { return GetValue<ObservableCollection<Field>>(FieldsProperty); }
set { SetValue(FieldsProperty, value); }
public static readonly PropertyData FieldsProperty = RegisterProperty("Fields", typeof(ObservableCollection<MappedField>));
}
BaseTabViewModel的孩子没有兴趣,因为除了一些[ViewModelToModel]
属性外,他们不与父母互动。
答案 0 :(得分:1)
如果您需要跨多个视图模型管理状态,我总是建议引入服务。视图模型可以存活很短或很长一段时间,但视图模型之间的最佳通信仍然是保持状态的服务(即使vm已经消失)。
以下是我对沟通的偏好:
我知道很多人用3解决他们的架构问题,但这是一个黑客,而不是一个可靠的解决方案。只需实现一个服务(注入所有vm&#39;),如下所示:
public class FieldCollectionManagementService : IFieldCollectionManagementService
{
private ObservableCollection<Field> _selectedCollection;
public ObservableCollection<Field> SelectedCollection
{
get { return _selectedCollection; }
set
{
_selectedCollection = value;
SelectedCollectionChanged.SafeInvoke(this);
}
}
public event EventHandler<EventArgs> SelectedCollectionChanged;
}
现在,您可以轻松处理所有更改,而无需使用属性。然后,当所有视图模型都消失时,您甚至可以恢复状态。