как привязать разные tabItems к различным ViewModels - PullRequest
1 голос
/ 21 апреля 2011

, как следует из названия, я не хочу помещать все это в одну ViewModel, я хочу иметь одну viewModel для tabItem, но я новичок в WPF и MVVM, поэтому, пожалуйста, держитесь со мной.

Я создал mainViewModel для окна, содержащего TabControl, где у меня есть это свойство currentViewModel, указывающее на значение по умолчанию в конструкторе mainViewModel

    public MainViewModel()
    {
        currentViewModel = "viewModel1";
    }

Когда пользователь нажимает на другую закладку, выполняется это

currentViewModel = "viewModel2";

и, конечно, в наборе доступа используется метод onPropertyChanged

    public String currentViewModel
    {
        get { return _currentViewModel; }

        set
        { 
            _currentViewModel = value;
            OnPropertyChanged("currentViewModel");
        }
    }

еще две viewModel (viewModel1, viewModel2), каждая из которых определяет функциональность одной из закладок, между которыми я хочу переключаться.

Теперь в моем файле Main.xaml я хочу привязать свой dataContext сначала к MainViewModel, а затем к свойству currentViewModel. так что всякий раз, когда пользователь нажимает на tabItem, свойство currentViewModel обновляется, а dataContext указывает на соответствующую модель представления. Я надеюсь, что это достаточно ясно

Заранее спасибо

Ответы [ 2 ]

2 голосов
/ 21 апреля 2011

Я думаю, что хорошим подходом было бы создание пользовательских элементов управления для каждого элемента вкладки.Затем в каждом пользовательском контроле вы будете ссылаться на правильное пространство имен viewModel для привязки.

Ваше MainWindow будет иметь tabcontrol, и каждый tabitem внутри tabcontrol будет связан с определенным usercontrol (который обрабатывается как отдельный View).

mainwindow_View.xaml будет привязан к mainwindow_ViewModel.cs tabItem1_View.xaml будет связан с ViewModel1.cs tabItem2_View.xaml будет связан с ViewModel2.cs

Если вам нужен пример кода, дайте мне знать.

2 голосов
/ 21 апреля 2011

Я сомневаюсь, что это то, что вы действительно хотите сделать, если у вас есть разные ViewModels, вы все равно можете связать свой элемент управления с коллекцией этих ViewModels и шаблонировать их по мере необходимости.Шаблоны данных на другом уровне, вот пример (который напрямую использует модели, но это не должно иметь значения прямо сейчас):

<TabControl>
    <TabControl.ItemsSource>
        <!-- This is just sample data, normally you would bind this to an
             ObservableCollection<ViewModelBase> or something similar -->
        <x:Array Type="{x:Type sys:Object}">
            <local:Employee Name="John" Occupation="Programmer"/>
            <local:Employee Name="Steve" Occupation="Coffee Getter"/>
            <local:Machine Manufacturer="iCorp" Model="iMachine"/>
            <local:Machine Manufacturer="iCorp" Model="iMachine G2"/>
            <local:Employee Name="Marc" Occupation="GUI Designer"/>
        </x:Array>
    </TabControl.ItemsSource>
    <TabControl.Resources>
        <!-- These datatemplates define the tab-header appearance, by placing them
             in the TabControl.Resources and setting the DataType they get applied
             automatically, just make one light-weight template for each ViewModel -->
        <DataTemplate DataType="{x:Type local:Employee}">
            <TextBlock>
                <Run Text="{Binding Name}"/>
                <Run Text="("/>
                <Run Text="{Binding Occupation}"/>
                <Run Text=")"/>
            </TextBlock>
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:Machine}">
            <TextBlock>
                <Run Text="{Binding Manufacturer}"/>
                <Run Text=" - "/>
                <Run Text="{Binding Model}"/>
            </TextBlock>
        </DataTemplate>

        <ContentControl x:Key="MainContent" Content="{Binding}">
            <ContentControl.Resources>
                <!-- This represents the content of the TabItems, you probably
                     do not need to create DataTemplates but since you could
                     use a View of the ViewModels instead -->
                <DataTemplate DataType="{x:Type local:Employee}">
                    <StackPanel>
                        <TextBlock Text="{Binding Name}"/>
                        <TextBlock Text="{Binding Occupation}"/>
                        <TextBlock Text="{Binding Id}"/>
                        <TextBlock Text="{Binding IsActive}"/>
                    </StackPanel>
                </DataTemplate>
                <DataTemplate DataType="{x:Type local:Machine}">
                    <StackPanel>
                        <TextBlock Text="{Binding Manufacturer}"/>
                        <TextBlock Text="{Binding Model}"/>
                        <TextBlock Text="{Binding VintageYear}"/>
                        <TextBlock Text="{Binding Price}"/>
                    </StackPanel>
                </DataTemplate>
            </ContentControl.Resources>
        </ContentControl>
    </TabControl.Resources>
    <TabControl.ContentTemplate> <!-- Setting the content to the resource -->
        <DataTemplate>
            <Border>
                <StaticResource ResourceKey="MainContent"/>
            </Border>
        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl>

Я мог бы попытаться реализовать специфику для MVVM, но, надеюсь, это уже дает представлениекак к нему можно подойти.

Возможно, вы захотите настроить селектор шаблонов (TabControl.ContentTemplateSelector), чтобы получить правильные представления для ваших ViewModels.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...