gpt4 book ai didi

c# - 如何设置ViewModela View的xaml的数据上下文?

转载 作者:行者123 更新时间:2023-12-03 10:55:00 24 4
gpt4 key购买 nike

我正在尝试将View的数据上下文设置为其ViewModel中包含的列表。但是,当我测试了当前设置时,似乎ViewModel和View之间的data context设置不正确。

要调试此问题,我在View的构造函数中设置了一个消息框,并收到以下错误消息,提示未正确设置数据上下文:“对象引用未设置为对象的实例”

该列表还用于另一个ViewModel中,该ViewModel显示该列表不为空,这进一步暗示了数据上下文问题。

有谁知道在View和ViewModel之间设置数据上下文的缺陷是什么?

这是包含列表的ViewModel:

namespace LC_Points.ViewModel
{
public class ViewSubjectGradeViewModel
{


public ViewSubjectGradeViewModel()
{

AddedSubjectGradePairs = new ObservableCollection<ScoreModel>();

}


public ObservableCollection<ScoreModel> AddedSubjectGradePairs { get; set; }

}
}

这是后面的“查看”和“查看”代码:
<Page x:Class="LC_Points.View.ViewSubjectGradePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:LC_Points.View"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vms="using:LC_Points.ViewModel"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
DataContext="{Binding ViewSubjectGradeViewModelProperty1}"
mc:Ignorable="d">



<Grid x:Name="LayoutRoot">

<Grid.ChildrenTransitions>
<TransitionCollection>
<EntranceThemeTransition />
</TransitionCollection>
</Grid.ChildrenTransitions>

<Grid.RowDefinitions>
<RowDefinition Height="40*" />
<RowDefinition Height="20*" />
<RowDefinition Height="30*" />
<RowDefinition Height="30*" />
<RowDefinition Height="20*" />
<RowDefinition Height="20*" />
</Grid.RowDefinitions>

<!-- Title Panel -->
<StackPanel Grid.Row="0" Margin="19,0,0,0">
<TextBlock Margin="0,12,0,0"
Style="{ThemeResource TitleTextBlockStyle}"
Text="LC POINTS" />
<TextBlock Margin="0,-6.5,0,26.5"
CharacterSpacing="{ThemeResource PivotHeaderItemCharacterSpacing}"
Foreground="DarkGreen"
Style="{ThemeResource HeaderTextBlockStyle}"
Text="View Grades" />
</StackPanel>

<!-- TODO: Content should be placed within the following grid -->
<Grid x:Name="ContentRoot"
Grid.Row="1"
Margin="19,9.5,19,0">

<ListBox Height="400"
Margin="0,0,0,-329"
VerticalAlignment="Top"
ItemsSource="{Binding AddedSubjectGradePairs}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<Run Text="{Binding Subject}" /><Run Text=" - " /><Run Text="{Binding Points}" />
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

</Grid>
</Grid>
</Page>

查看后面的代码:
namespace LC_Points.View
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class ViewSubjectGradePage : Page
{
private NavigationHelper navigationHelper;
private ObservableDictionary defaultViewModel = new ObservableDictionary();


public ViewSubjectGradePage()
{
this.InitializeComponent();

this.navigationHelper = new NavigationHelper(this);
this.navigationHelper.LoadState += this.NavigationHelper_LoadState;
this.navigationHelper.SaveState += this.NavigationHelper_SaveState;

var messageDialog = new MessageDialog(DataContext.GetType().ToString());
messageDialog.ShowAsync();
}

/// <summary>
/// Gets the <see cref="NavigationHelper"/> associated with this <see cref="Page"/>.
/// </summary>
public NavigationHelper NavigationHelper
{
get { return this.navigationHelper; }
}


/// <summary>
/// Gets the view model for this <see cref="Page"/>.
/// This can be changed to a strongly typed view model.
/// </summary>
public ObservableDictionary DefaultViewModel
{
get { return this.defaultViewModel; }
}



private void NavigationHelper_LoadState(object sender, LoadStateEventArgs e)
{
}


private void NavigationHelper_SaveState(object sender, SaveStateEventArgs e)
{
}

#region NavigationHelper registration


protected override void OnNavigatedTo(NavigationEventArgs e)
{
this.navigationHelper.OnNavigatedTo(e);
}

protected override void OnNavigatedFrom(NavigationEventArgs e)
{
this.navigationHelper.OnNavigatedFrom(e);
}

#endregion
}
}

最佳答案

您可能想要从View的代码中删除该模板提供您未使用的任何生成的代码。这可能引起困惑,因为模板希望您使用本地的ObservableCollection作为DataContext。

将ViewModel设置为View的DataContext的主要方法有3种。

  • 使用 View 后面的代码:
    public ViewSubjectGradePage()
    {
    this.InitializeComponent();
    this.DataContext = new ViewSubjectGradeViewModel();
    }
  • 使用XAML(已删除其他Page属性以便于阅读):
    <Page x:Class="LC_Points.View.ViewSubjectGradePage"
    xmlns:vms="using:LC_Points.ViewModel">
    <Page.DataContext>
    <vms:ViewSubjectGradeViewModel/>
    </Page.DataContext>
    </Page>
  • 使用像Prism这样的MVVM框架。这将根据标准命名约定自动连接View和ViewModel。

  • 我更喜欢选项3,因为它可以提供更为松散的耦合系统,但是对于一个非常小的项目而言可能会显得有些过激,而且任何框架都可以学习,但是这样做的好处却是巨大的。选项2是我的第二个投票,因为它使代码更清洁。选项1是我不再要做的事情,但是它是使它正常工作的好方法。

    关于c# - 如何设置ViewModela View的xaml的数据上下文?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30689082/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com