samedi 6 juin 2015

How to set data context of ViewModela View's xaml?

I'm trying to set the data context of a View to the list contained in it's ViewModel. But when I've tested the current set up, it seems the data context between the ViewModel and View is set incorrectly.

To debug this issue I set up a message box in the constructor of my View, and I get the following error message, which hints at the data context not being set correctly: "Object reference not set to an instance of an object"

The list is also used in another ViewModel which shows that the list is not empty, which hints further at a data context issue.

Does anyone know what the flaw is in setting up the data context between the View and ViewModel?

This is the ViewModel containing the list:

namespace LC_Points.ViewModel
{
    public class ViewSubjectGradeViewModel 
    {


        public ViewSubjectGradeViewModel()
        {

            AddedSubjectGradePairs = new ObservableCollection<ScoreModel>();

        }


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

    }
}

And this is the View and View code behind:

<Page x:Class="LC_Points.View.ViewSubjectGradePage"
      xmlns="http://ift.tt/o66D3f"
      xmlns:x="http://ift.tt/mPTqtT"
      xmlns:d="http://ift.tt/pHvyf2"
      xmlns:local="using:LC_Points.View"
      xmlns:mc="http://ift.tt/pzd6Lm"
      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>

View code behind:

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
    }
}

Error that's thrown in the message box of the View code behind constructor:

null data exception on data context

Aucun commentaire:

Enregistrer un commentaire