wpf - 从代码隐藏设置用户控件的 DataContext

标签 wpf vb.net mvvm user-controls datacontext

这应该很容易,但它会引发 VS2008 的严重循环。

我正在尝试使用 MVVM 的 WPF,尽管我已经开发了大约 15 年,并且有一个比较,但我还是一个新手。科学。程度。在当前客户端,我需要使用 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>

我还有一个名为 DataView 的 UserControl,它由一个 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 绑定(bind)到 View 模型来设置它,如下所示:
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 的 View 模型如下所示(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

现在,如果我在 XAML 中实例化它,这个 UserControl 就可以正常工作。当我运行代码时,网格会显示出来并很好地填充它。

但是,网格需要很长时间才能加载其数据,我想在单击按钮后以编程方式创建此用户控件,而不是在 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 完成,我的应用程序就会锁定,开始占用 RAM,并占用大约 50% 的 CPU。

我没有正确实例化我的 UserControl 吗?这一切似乎都归结为 DataEntry 构造函数中的 DataContext 分配。如果我将其注释掉,则该应用程序将按预期工作(当然,网格中没有任何内容)。

如果我将此代码块移动到 Button1_Click (基本上将 DataEntry 的构造函数代码向上移动一个级别),应用程序仍然失败:
dataViewModel = New ViewModels.DataViewModel
dataViewModel.LoadDataEntries()
dataView.DataContext = dataViewModel

我难住了。谁能给我一些关于我可能做错了什么的提示,或者甚至如何调试我的应用程序正在进入的无限循环?

非常感谢。

最佳答案

问题的根本原因似乎是您正在加载的原始数据量或加载该数据的方式效率低下。话虽如此,您看到应用程序锁定的原因是您在加载数据时锁定了 UI 线程。

我相信在您的第一种情况下,数据加载已被卸载到另一个线程以加载数据。在第二个示例中,您在 UI 线程上实例化控件,因此所有构造函数和加载逻辑都在当前线程(UI 线程)上执行。如果您将此工作卸载到另一个线程,那么您应该会看到与第一个示例类似的结果。

关于wpf - 从代码隐藏设置用户控件的 DataContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1100280/

相关文章:

wpf - telerik 忙指示器不可见

c# - C# 中 Visual Basic 的 And 和 Or 是否等效?

.net - DialogResult 关闭设置对通过 ShowDialog() 显示的表单有影响吗?

vb.net - 什么是事件参数 "sender"和 "e"

c# - 通知集合中某项的属性更改

android - Kotlin Flow - callbackFlow 的替代品

c# - 如何在 Nunit 中调用 WPF Dispatcher?

c# - 为什么这个可编辑的 ComboBox 中的插入符超出范围?

c# - 如何解决泛型类 <T> 场景?

c# - wpf绑定(bind)问题