Указание одной из нескольких таблиц данных WPF для отображения во время выполнения - PullRequest
1 голос
/ 16 февраля 2012

В моем приложении я хотел бы иметь выпадающий список для выбора таблицы для редактирования (около 20). Каждая таблица должна быть представлена ​​своей собственной таблицей данных WPF. (Я думал об использовании единой DataGrid и создании набора новых столбцов во время выполнения с выделенным кодом, но это не очень похоже на XAML.)

Мой раскрывающийся список находится в пользовательском элементе управления (поскольку он является частью более крупного приложения). Я считаю (из моего исследования), что заполнителем для одной из 20 DataGrids должен быть ContentControl, используемый в качестве заполнителя здесь:

<UserControl x:Class="MyClass" ...
         xmlns:my="clr-namespace:MyNamespace"
         DataContext="{Binding ViewModel}">
<StackPanel>
    <Grid>
        <ComboBox Name="DataPaneComboBox" HorizontalAlignment="Stretch" 
                  IsReadOnly="True" MinWidth="120" 
                  Focusable="False" SelectedIndex="0"
                  DockPanel.Dock="Left" Grid.Column="0"
                  SelectionChanged="DataPaneComboBox_SelectionChanged">
            <ComboBoxItem Name="FirstOption" Content="Choice 1" />
            <ComboBoxItem Name="SecondOption" Content="Choice 2" />
            <ComboBoxItem Name="ThirdOption" Content="Choice 3" />
        </ComboBox>
    </Grid>
    <ContentControl Name="DataGridView" Margin="0,3,0,3" Content="{Binding CurrentView}" />
</StackPanel>

Вот мой код для этого класса:

public partial class MyClass : UserControl {
    private MyViewModel ViewModel {
        get; set;
    }

    public MyClass() {
        InitializeComponent();
        ViewModel = new MyViewModel();
        ViewModel.CurrentView = new DataGridChoice1();
    }
}

И ViewModel (класс ObservableObject реализует интерфейс INotifyPropertyChanged):

public class MyViewModel : ObservableObject {
    private UserControl _currentView;

    public UserControl CurrentView {
        get {
            if (this._currentView == null) {
                this._currentView = new DatGridChoice1();
            }

            return this._currentView;
        }
        set {
            this._currentView = value;
            RaisePropertyChanged("CurrentView");
        }
    }
    #endregion
}

И один из 20 или около того пользовательских элементов управления, которые можно заменить во время выполнения:

<UserControl x:Class="Choice1Control"
             xmlns:my="clr-namespace:MyNamespace">
    <DataGrid ItemsSource="{Binding Choice1Objects}" />
        <!-- ... -->
    </DataGrid>
</UserControl>

Когда пользователь меняет раскрывающийся список, я бы хотел, чтобы программа загрузила соответствующую DataGrid. Сейчас я не вижу дочерний UserControl (здесь, Choice1Control). Я добавил ребенка напрямую (без промежуточного ContentControl), и он отлично работает.

Я пробовал почти каждую комбинацию привязки контента DataContext и UserControl. Я новичок в WPF, поэтому я, вероятно, упускаю что-то явно очевидное. Спасибо!

Ответы [ 2 ]

1 голос
/ 16 февраля 2012

Путь нуждается в источнике, чтобы идти против (Source, DataContext, RelativeSource, ElementName).ElementName может использоваться только для ссылки на элементы, объявленные в XAML их x: Name.

0 голосов
/ 16 февраля 2012

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

Кажется, что DataContext корневого UserControl перехватывался до того, как он мог быть унаследован ContentControl.(Или мое представление о том, как DataContext наследуется / распространяется, неверно.)

В конце я изменил конструктор MyClass, чтобы явно указать DataContext как ViewModel.

public MyClass() {
    InitializeComponent();
    ViewModel = new MyViewModel();
    ViewModel.CurrentView = new DataGridChoice1();            
    this.DataContext = ViewModel;                      // <-- Added this line
}

Затем привязки работают должным образом, и я могу переключаться между несколькими DataGrids, когда раскрывающийся список меняет состояние.

Мне бы хотелось услышать, почему первоначальная привязка была неправильной.Однако теперь я буду претендовать на небольшую победу и оставлю эту головоломку на следующий день.

...