Это должно быть довольно легко, но это бросает VS2008 для серьезного цикла.
Я пробую WPF с MVVM, и я новичок в этом, хотя я занимаюсь разработкой около 15 лет и у меня есть комп. Sci. степень. На текущем клиенте я обязан использовать VB.Net.
Я переименовал свои собственные переменные и удалил некоторые отвлекающие факторы в коде ниже, поэтому, пожалуйста, прости меня, если он не на 100% синтаксически совершенен! Вам, вероятно, не нужен код, чтобы понять вопрос, но я включаю его на случай, если он поможет.
У меня очень простой файл MainView.xaml:
<Window x:Class="MyApp.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Main Window" Height="400" Width="800" Name="MainWindow">
<Button Name="Button1">Show Grid</Button>
<StackPanel Name="teststack" Visibility="Hidden"/>
</Window>
У меня также есть UserControl, называемый DataView, который состоит из DataGrid:
<UserControl x:Class="MyApp.Views.DataView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:WpfToolkit="http://schemas.microsoft.com/wpf/2008/toolkit" >
<Grid>
<WpfToolkit:DataGrid
ItemsSource="{Binding Path=Entries}" SelectionMode="Extended">
</WpfToolkit:DataGrid>
</Grid>
</UserControl>
Конструктор для пользовательского управления DataView устанавливает DataContext, привязывая его к модели представления, как показано здесь:
Partial Public Class DataView
Dim dataViewModel As ViewModels.DataViewModel
Public Sub New()
InitializeComponent()
dataViewModel = New ViewModels.DataViewModel
dataViewModel.LoadDataEntries()
DataContext = dataViewModel
End Sub
End Class
Модель представления для DataView выглядит следующим образом (в ViewModelBase не так много):
Public Class DataViewModel
Inherits ViewModelBase
Public Sub New()
End Sub
Private _entries As ObservableCollection(Of DataEntryViewModel) = New ObservableCollection(Of DataEntryViewModel)
Public ReadOnly Property Entries() As ObservableCollection(Of DataEntryViewModel)
Get
Return _entries
End Get
End Property
Public Sub LoadDataEntries()
Dim dataEntryList As List(Of DataEntry) = DataEntry.LoadDataEntries()
For Each dataentry As Models.DataEntry In dataEntryList
_entries.Add(New DataEntryViewModel(dataentry))
Next
End Sub
End Class
Теперь этот UserControl работает просто отлично, если я его создаю в XAML. Когда я запускаю код, сетка обнаруживается и заполняет его просто отлично.
Однако для загрузки данных в сетку требуется много времени, и я хочу создать этот пользовательский элемент управления программно после нажатия кнопки, а не декларативно создавать экземпляр сетки в XAML. Я хочу создать экземпляр пользовательского элемента управления и вставить его как дочерний элемент элемента управления StackPanel:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
Dim dataView As New DataView
teststack.Children.Add(dataView)
End Sub
Когда я делаю это, как только заканчивается Button1_Click, мое приложение блокируется, начинает использовать оперативную память и загружает процессор примерно на 50%.
Правильно ли я создаю экземпляр своего UserControl? Кажется, все сводится к назначению DataContext в конструкторе DataEntry. Если я это прокомментирую, приложение работает как положено (конечно, без сетки).
Если я переместу этот блок кода в Button1_Click (в основном переместив код конструктора DataEntry на уровень выше), приложение все равно завершится ошибкой:
dataViewModel = New ViewModels.DataViewModel
dataViewModel.LoadDataEntries()
dataView.DataContext = dataViewModel
Я в тупике. Кто-нибудь может дать мне несколько советов о том, что я могу делать неправильно, или даже как отлаживать бесконечный цикл, в который попадает мое приложение?
Большое спасибо.