Почему контент не отображается после передачи SelectedItem в качестве пользовательского объекта на новую страницу? - PullRequest
0 голосов
/ 10 июня 2018

Я очень новичок в Xamarin и C #.Так что, если я прошу новичка, я прошу прощения.Но я исследовал interwebz и Stack Overflow, чтобы выяснить, почему то, что я делаю, не работает и не могу понять.Насколько я могу судить, все должно работать нормально, но, может быть / надеюсь, я просто упускаю что-то простое.

Я использую MVVM (в основном), и у меня есть ListView, состоящий из объектов, который называется MobileBoardUser.Это представление списка настроено так:

<ListView
        ItemsSource="{Binding BoardUsers}"
        HasUnevenRows="True"
        ItemSelected="StatusBoardPageListView_ItemSelected" >
        <ListView.ItemTemplate >
            <DataTemplate>
                <ViewCell>
                    //then the various StackLayout and Label objects etc.

. В приведенном ниже коде я пытаюсь использовать метод ItemSelected для передачи выбранного элемента на новую страницу, где будут отображаться все его свойства.

private void StatusBoardPageListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
    {
        if (e.SelectedItem == null)
        {
            return; 
        }
        MobileBoardUser userSelected = e.SelectedItem as MobileBoardUser;
        Navigation.PushAsync(new BoardUserPage(userSelected));
    }

Код BoardUserPage Behind выглядит следующим образом

using EIOBoardMobile.Model;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text; 
using System.Threading.Tasks;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace EIOBoardMobile.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class BoardUserPage : ContentPage
{
    public class UserProp
    {
        public string userprop { get; set; }
    }

    public class UserValue
    {
        public string uservalue { get; set; }
    }

    public ObservableCollection<UserProp> SelectedUserProps { get; set; } = new ObservableCollection<UserProp>();
    public ObservableCollection<UserValue> SelectedUserValues { get; set; } = new ObservableCollection<UserValue>();

    public BoardUserPage(MobileBoardUser selectedUser)
    {
        InitializeComponent();
        BindingContext = this;
        MobileBoardUser shownUser = selectedUser;

        foreach (var prop in shownUser.GetType().GetProperties())
        {
            if (prop.GetType() == typeof(String))
            {
                UserProp NewUserProp = new UserProp
                {
                    userprop = prop.Name.ToString()
                };
                SelectedUserProps.Add(NewUserProp);
            }
        }
        foreach (var prop in shownUser.GetType().GetProperties())
        {
            if (prop.GetType() == typeof(String))
            {
                UserValue NewUserValue = new UserValue
                {
                    uservalue = prop.GetValue(shownUser, null).ToString()
                };
                SelectedUserValues.Add(NewUserValue);
            }
        }
    }
  }
}

Как вы можете видеть, я создал два списка объектов, один для представления имен свойств и один для представления фактических значений этих свойств.поэтому они могут быть использованы в xaml.В производстве они будут динамичными, поэтому важно, чтобы я мог сделать это таким образом.С этой целью xaml BoardUserPage выглядит следующим образом

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:local="clr-namespace:EIOBoardMobile.Views"
         x:Class="EIOBoardMobile.Views.BoardUserPage">
<ContentPage.Content>
    <StackLayout Padding="20">
        <ListView 
            ItemsSource="{Binding SelectedUserProps}"
            HasUnevenRows="True" >
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout Orientation="Vertical" >
                            <Label Text="{Binding userprop}" HorizontalOptions="StartAndExpand" TextColor="Black" />
                                <ListView ItemsSource="{Binding SelectedUserValues}" HorizontalOptions="EndAndExpand" >
                                    <ListView.ItemTemplate>
                                        <DataTemplate>
                                            <ViewCell>
                                                <Label Text="{Binding uservalue}" HorizontalOptions="EndAndExpand" TextColor="Blue" />
                                            </ViewCell>
                                        </DataTemplate>
                                    </ListView.ItemTemplate>
                                </ListView>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage.Content>
</ContentPage> 

Все это компилируется, и я не получаю необработанных исключений или ошибок времени выполнения.Код, который передает SelectedItem как MobileBoardUser на новую страницу, работает для перехода к BoarduserPage, но когда я туда попадаю, страница пуста и ничего не делает.

Что я сделал не так?

1 Ответ

0 голосов
/ 10 июня 2018

Хорошо, после некоторых проб и ошибок, я действительно смог понять это.Мне пришлось внести некоторые изменения в код.Операторы typeof не были сконструированы должным образом.Для SelectedUserProps я получал typeof свойство, а не значение.Так что я должен был это изменить.Также вложенный ListView внутри другого ListView вызывал исключения и не мог генерировать.Передача e.SelectedItem после приведения фактически ДЕЛАЛА работу.Это были утверждения сравнения foreach, которые вызывали у меня горе.Итак, основные изменения, которые я сделал, касались кода BoardUserPage и BoardUserPage xaml.Вот эти изменения.В первую очередь используется один ObservableCollection вместо двух (следовательно, теперь только один оператор foreach и исправление сравнения типов, чтобы я сравнивал значения вместо самих свойств с typeof (String). Вот код, стоящий за

using EIOBoardMobile.Model;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace EIOBoardMobile.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class BoardUserPage : ContentPage
    {
        public class UserProp
        {
            public string userprop { get; set; }
            public string uservalue { get; set; }
        }

        public ObservableCollection<UserProp> SelectedUserProps { get; set; } = new ObservableCollection<UserProp>();

        public BoardUserPage(MobileBoardUser selectedUser)
        {
            InitializeComponent();
            BindingContext = this;


            foreach (var prop in selectedUser.GetType().GetProperties())
            {

                if (prop.GetValue(selectedUser).GetType() == typeof(String))
                {
                    UserProp NewUserProp = new UserProp
                    {
                        userprop = prop.Name.ToString(),
                        uservalue = prop.GetValue(selectedUser).ToString()
                    };
                    SelectedUserProps.Add(NewUserProp);
                }
            }
        }
    }
}

а здесь - представление (xaml)

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:EIOBoardMobile.Views"
             x:Class="EIOBoardMobile.Views.BoardUserPage">

        <StackLayout Padding="20" >
        <ListView 
                x:Name="Parent"
                ItemsSource="{Binding SelectedUserProps}"
                HasUnevenRows="True" >
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <StackLayout Orientation="Vertical" Padding="10" HeightRequest="100">
                                <Label Text="{Binding userprop}" HorizontalOptions="StartAndExpand" VerticalOptions="StartAndExpand" TextColor="Black" />
                                <Label Text="{Binding uservalue}" HorizontalOptions="EndAndExpand" VerticalOptions="EndAndExpand" TextColor="Blue" />
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackLayout>
</ContentPage>

. Здесь отображаются имена свойств слева и значения справа только для тех свойств, которые являются строками. Это было необходимо, чтобы избежать отображения идентификаторов и другого целочисленного ключа.значения из базы данных, которые были бы просто бесполезными помехами для конечных пользователей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...