选中tabitem的viewmodel属性

时间:2015-04-10 08:13:55

标签: wpf xaml mvvm tabcontrol catel

我有UserControl ParentView ,其中包含DataGridcatel:TabControl,其中每个TabItem都很小UserControl ViewModel 是BaseTabViewModel的子类

BaseTabViewModel包含自定义类的ObservableCollection,其属性将生成DataGrid的列。

由于我的所有标签只有一个DataGrid,如何自动填充选定标签的viewmodel的ObservableCollection?

enter image description here

现在,我只是卸载标签(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]属性外,他们不与父母互动。

1 个答案:

答案 0 :(得分:1)

如果您需要跨多个视图模型管理状态,我总是建议引入服务。视图模型可以存活很短或很长一段时间,但视图模型之间的最佳通信仍然是保持状态的服务(即使vm已经消失)。

以下是我对沟通的偏好:

  1. 服务(最佳方式,允许完全控制,最佳性能)
  2. 基于属性的沟通
  3. 消息传递(MessageMediator)
  4. 我知道很多人用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;
    }
    

    现在,您可以轻松处理所有更改,而无需使用属性。然后,当所有视图模型都消失时,您甚至可以恢复状态。