Как да обвържете наблюдаема колекция към ListView

Настроих обвързването на ListView, следвайки този пример, обвързване към наблюдаема колекция но когато стартирам приложението, стойностите на колекцията не се показват в ListView.

Изходният прозорец не извежда никакви грешки при обвързване, така че не съм сигурен каква може да е грешката при обвързване. Също така съм задал точка на прекъсване в списъка, преди да бъде изпратен до втората виртуална машина и е попълнен, т.е. не е нула.

Предполагам, че списъкът е нулев във втората виртуална машина, тъй като не се инициализира правилно след преминаване.

Може ли някой да посъветва как да се отстранят грешките, когато ListView е празен?

Това е наборът за обвързване в изгледа:

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

Контекстът на данните за изгледа е зададен както следва в кода отзад:

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 ViewSubjectGradeViewModel ViewModel;

        public ViewSubjectGradePage()
        {
            this.InitializeComponent();

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

            ViewModel = new ViewSubjectGradeViewModel();
            this.DataContext = ViewModel;
        }

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


        /// <summary>
        /// Populates the page with content passed during navigation.  Any saved state is also
        /// provided when recreating a page from a prior session.
        /// </summary>
        /// <param name="sender">
        /// The source of the event; typically <see cref="NavigationHelper"/>
        /// </param>
        /// <param name="e">Event data that provides both the navigation parameter passed to
        /// <see cref="Frame.Navigate(Type, Object)"/> when this page was initially requested and
        /// a dictionary of state preserved by this page during an earlier
        /// session.  The state will be null the first time a page is visited.</param>
        private void NavigationHelper_LoadState(object sender, LoadStateEventArgs e)
        {
        }

        /// <summary>
        /// Preserves state associated with this page in case the application is suspended or the
        /// page is discarded from the navigation cache.  Values must conform to the serialization
        /// requirements of <see cref="SuspensionManager.SessionState"/>.
        /// </summary>
        /// <param name="sender">The source of the event; typically <see cref="NavigationHelper"/></param>
        /// <param name="e">Event data that provides an empty dictionary to be populated with
        /// serializable state.</param>
        private void NavigationHelper_SaveState(object sender, SaveStateEventArgs e)
        {
        }

        #region NavigationHelper registration

        /// <summary>
        /// The methods provided in this section are simply used to allow
        /// NavigationHelper to respond to the page's navigation methods.
        /// <para>
        /// Page specific logic should be placed in event handlers for the  
        /// <see cref="NavigationHelper.LoadState"/>
        /// and <see cref="NavigationHelper.SaveState"/>.
        /// The navigation parameter is available in the LoadState method 
        /// in addition to page state preserved during an earlier session.
        /// </para>
        /// </summary>
        /// <param name="e">Provides data for navigation methods and event
        /// handlers that cannot cancel the navigation request.</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            this.navigationHelper.OnNavigatedTo(e);
        }

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

        #endregion
    }
}

И получаване на списъка във ViewSubjectGradeVM чрез конструктора:

namespace LC_Points.ViewModel
{
    public class ViewSubjectGradeViewModel 
    {


        public ViewSubjectGradeViewModel()
        {


        }

         /// <summary>
        /// Initializes a new instance of the ViewSubjectGradeViewModel class.
        /// </summary>
        public ViewSubjectGradeViewModel(IEnumerable<ScoreModel> addedSubjectGradePairs)
        {
            this.AddedSubjectGradePairsCopy = addedSubjectGradePairs;

        }


        //Property for collection passed from MainViewModel
        public IEnumerable<ScoreModel> AddedSubjectGradePairsCopy { get; set; }


    }
}

И това е поддържащият модел за списъка, предаван от MainVM към ViewSubjectGradeVM:

namespace LC_Points.Model
{
    public class ScoreModel : INotifyPropertyChanged
    {

        // The name of the subject.
        public string Subject { get; set; }


        // The points paired with each grade type.
        public int Points { get; set; }


        public event PropertyChangedEventHandler PropertyChanged;

        private void RaisePropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }


    }
}

person Brian J    schedule 23.05.2015    source източник
comment
Къде настройвате DataContext?   -  person Hamlet Hakobyan    schedule 24.05.2015
comment
Зададох контекста на данните в кода зад изгледа, сега ще публикувам редакция.   -  person Brian J    schedule 24.05.2015
comment
Да, но вие извиквате ctor по подразбиране, така че AddedSubjectGradePairsCopy е нула.   -  person Hamlet Hakobyan    schedule 24.05.2015
comment
добре, виждам това сега, просто трябва да се отърва от това тогава? hastebin.com/oretezoqot.cs   -  person Brian J    schedule 24.05.2015
comment
Не, премахнах конструктора по подразбиране, но ListView все още не показва никакво съдържание, някакви други идеи?   -  person Brian J    schedule 24.05.2015
comment
Не трябва да премахвате ctor по подразбиране. Имате нужда от нещо подобно ViewModel = new ViewSubjectGradeViewModel(GetScoreModels()); this.DataContext = ViewModel; вместо ViewModel = new ViewSubjectGradeViewModel(); this.DataContext = ViewModel;   -  person Hamlet Hakobyan    schedule 24.05.2015
comment
Така че мисля, че разбирам какво целиш, трябва да посоча параметъра, който моят ViewSubjectGradeViewModel приема. Опитах следното, но ми казва hastebin.com/ohihameyos.tex и това е моят опит : gist.github.com/BrianJVarley/87a051d400ea1c7ffcfb   -  person Brian J    schedule 25.05.2015


Отговори (1)


Опитайте нещо подобно. Разбира се, вашият модел трябва да идва от някакъв източник, който трябва да картографирате към вашия изгледмодел. Но това ви илюстрира начина за задаване на правилен контекст на данни.

var scoremodels = new List<ScoreModel>
{
    new ScoreModel {Subject = "Subj1", Points = 6},
    new ScoreModel {Subject = "Subj2", Points = 3},
    new ScoreModel {Subject = "Subj3", Points = 8},
}
ViewModel = new ViewSubjectGradeViewModel(scoreModels);
this.DataContext = ViewModel;
person Hamlet Hakobyan    schedule 24.05.2015
comment
Добре, ако разбирам правилно, трябва да дефинирам нещото, което се предава от MainVM към тази VM. Но когато опитам следното в кода на ViewSubjectGradePage отзад, компилаторът ми казва, че списъкът не съществува в текущия контекст. ` ViewModel = нов ViewSubjectGradeViewModel(AddedSubjectGradePairs); ` AddedSubjectGradePairs е списъкът, предаван от MainVM, който е съставен от ScoreModel. - person Brian J; 25.05.2015
comment
Какво сте опитвали? Показване на кода ViewSubjectGradePage. - person Hamlet Hakobyan; 27.05.2015
comment
Това е, което опитах, но компилаторът ми казва, че списъкът не съществува в текущия контекст, което е вярно, тъй като списъкът е в моята MainVM. Списъкът е наблюдаема колекция от тип ScoreModel, който е моят модел на данни. Моят код на ViewSubjectGradePage: gist.github.com/BrianJVarley/87a051d400ea1c7ffcfb и това е основната виртуална машина, където Предавам списъка към виртуалната машина на тази страница във viewGradesCommand RelayCommand: gist.github.com/BrianJVarley/3dd6e164029aeb67263d - person Brian J; 27.05.2015
comment
Не видях къде си създал MainViewModel. Освен това AddedSubjectGradePairs не е достъпен от ViewSubjectGradePage. - person Hamlet Hakobyan; 27.05.2015
comment
Това е MainViewModel, където се създава списъкът и се предава на другата виртуална машина: hastebin.com/alirebanup.cs - person Brian J; 01.06.2015
comment
Вашата колекция е празна. AddedSubjectGradePairs = new ObservableCollection<ScoreModel>(); - person Hamlet Hakobyan; 01.06.2015
comment
Колекцията не е празна, след като добавя двойки към нея при извикване на командата AddGrade. - person Brian J; 02.06.2015
comment
ViewSubjectGradeViewModel subjectGradeObj = new ViewSubjectGradeViewModel(AddedSubjectGradePairs); Този ред код е неуместен, защото сте загубили препратката към subjectGradeObj. - person Hamlet Hakobyan; 02.06.2015