2014-08-22 5 views
0

Хорошо, у меня здесь есть довольно сложная функциональность. Я хотел бы знать A) Если я делаю это правильно. Если нет, что я должен изменить? 2) Если это правильно, то каково наилучшее решение моей проблемы?WPF MVVM Легкие динамические виды и датаграфиты

У меня есть главное окно со списком элементов. Если я нажму на один из них, в правой колонке Grid в этом окне должно быть заполнено DataGrid информацией о выбранном элементе. Если я щелкнул другой элемент в ListView, он должен измениться на другой DataGrid.

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

DriverGrid.xaml

<UserControl DataContext="{Binding AdminDriver, Source={StaticResource Locator}}"> 
    <Grid> 

      <DataGrid> 
       //stuff here for datagrid 
      </DataGrid> 

      <Button Content="Edit" Command="{Binding ShowEditWindow}" /> 
      <Button Content="Add" Command="{Binding ShowAddWindow}"/> 
    </Grid> 
</UserControl> 

AdminDriver.cs (VM)

//Contains variables, and is the datacontext for the above usercontrol 

AdminMain.xaml (вид для всех админ материала)

//Contains a bunch of junk for the min admin screen which has the listview with the options in it. If you require this piece of code, I can trim it down but I don't se currently see it's relevance. The DataGrid belongs in this window, I'm assuming in a Content Presenter. Here is the ListView that is in column 1 of 2. 

<ListView ItemsSource="{Binding AdminMenu}" 
          Name="AdminFields" 
          SelectionMode="Single"> 
        <i:Interaction.Triggers> 
         <i:EventTrigger EventName="SelectionChanged"> 
          <cmd:EventToCommand CommandParameter="{Binding SelectedItem, ElementName=AdminFields}" Command="{Binding registerSelected}"/> 
         </i:EventTrigger> 
        </i:Interaction.Triggers> 
        <ListView.ItemTemplate> 
         <ItemContainerTemplate> 
          <TextBlock Text="{Binding FieldName}"/> 
         </ItemContainerTemplate> 
        </ListView.ItemTemplate> 
       </ListView> 

ответ

1

Я взял привязку DataContext из UserControl. Это позволит вам использовать его в других местах, если вам когда-либо понадобится. Вместо этого просто привяжите DataContext, где вы его используете.

<view:YourUserControl DataContext="{Binding AdminDriver}" /> 

Если вы хотите, чтобы представить различные UserControls основанные на какой элемент выбран в ListView, то вы будете использовать ContentPresenter. Все элементы в вашем ItemsSource будут иметь тот же базовый класс или реализовать один и тот же интерфейс, чтобы вы могли поместить их в тот же ObservableCollection. Я предполагаю, что AdminDriver будет такого типа/интерфейса, как и тогда.

Вы должны установить некоторые DataTemplates в верхней части окна, которые сопоставляют возможные реальные типы объектов в вашем ItemsSource (AdminMenu) с UserControl, которые будут их представлять.

<Window.Resource> 
    <DataTemplate DataType="{x:Type model:TypeA}"> 
     <view:UserControlA /> 
    </DataTemplate> 

    <DataTemplate DataType="{x:Type model:TypeB}"> 
     <view:UserControlB /> 
    </DataTemplate> 
    //rinse and repeat 
</Window.Resource> 

Тогда вы будете добавлять ContentPresenter к сетке и связать это DataContext свойству AdminDriver. Появится UserControl, соответствующий фактическому типу выбранного элемента, отображаемому в ваших DataTemplates.

<ContentPresenter Content="{Binding AdminDriver}" /> 
+0

Не могли бы вы объяснить модель: TypeA для меня? Я прочитал ваше предложение «Все элементы в вашем ItemsSource будут иметь тот же базовый класс или реализовать один и тот же интерфейс, чтобы вы могли поместить их в один и тот же ObservableCollection». OC не являются одним и тем же типом данных. И нет базового класса для коллекций. Еще одно замечание, также будет один элемент меню DataGrid/UserControl для EACH. Поверьте мне, я пробовал это, используя только один, но это не вариант для каждого запроса на дизайн команды. Его нужно разбить. – JTester

+0

Итак, коллекция AdminMenu ObservableCollection ? Вы говорите мне, что команда registerSelected устанавливает разные свойства в зависимости от того, какой элемент в ListView выбран? –

+0

Да: this.registerSelected = new RelayCommand ((selectedMenuItem) => { this.SelectedMenuItem = selectedMenuItem.FieldName; }); Так что в нашем маленьком примере это.SelectedMenuItem = «Драйвер» – JTester