Привязка SelectedItem к корневому интерфейсу NavPage из ListView другого NavPage не работает - PullRequest
0 голосов
/ 06 декабря 2018

Я хотел использовать правую кнопку NavBar в качестве функции фильтра для моего ListView.Моим первым подходом был выпадающий список, но поскольку в iOS это невозможно, я попытался обойти это с помощью пакета NuGet Rg.Plugins.Popup (я не хотел создавать CustomRenderer).Пока все работает нормально.

Мой пользовательский интерфейс не обновляется после выбора из моего другого ListView.Что касается отладки, мои значения меняются правильно.

Вот мой ViewModel:

public ProcessesPageViewModel()
        {
            Location = new Location { Name = "Default", Filter = "Default" };
            AsyncCreateListLocations();
        }

AsyncCreateListLocations () - это просто задача, выполняющая это:

void CreateListLocations()
    {
        downloadLocations = new DownloadLocations();
        LocationList = downloadLocations.DownloadJSON().OrderBy(x => x.Name).ToList();
    }

private Location _location;
public Location Location
    {
        get => _location;
        set
        {
            SetValue(ref _location, value);
        }
    }

Мой XAML изкорневой ListView, к которому фильтр должен применяться позднее (пока не реализовано):

<ContentPage.ToolbarItems>
    <ToolbarItem Text="{Binding Location.Name}" Clicked="Clicked_Location"/>
</ContentPage.ToolbarItems>

Теперь это моя всплывающая страница с местоположениями в виде ListView:

<ListView x:Name="ProcessesListView"
              ItemsSource="{Binding LocationList}"
              SelectedItem="{Binding Location}"
              WidthRequest="100"
              HeightRequest="200"
              ItemSelected="OnItemSelected"
              VerticalOptions="Center">

        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>
                        <Label Margin="5" FontAttributes="Bold" VerticalOptions="FillAndExpand" Grid.Row="0" Grid.ColumnSpan="2" Text="{Binding Name}" />
                    </Grid>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>


async void OnItemSelected(object sender, SelectedItemChangedEventArgs args)
        {
            await Navigation.PopPopupAsync();
        }

РЕДАКТИРОВАТЬ с использованием Acr.UserDialogs:

using Acr.UserDialogs;
using MyProject.Models;
using MyProject.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace MyProject.ViewModels
{
    public class MyViewModel : BaseViewModel
    {
        private IUserDialogs userDialogs;
        public MyViewModel(IUserDialogs userDialogs)
        {
            this.userDialogs = userDialogs;
        }
        DownloadProcesses downloadProcesses;
        DownloadLocations downloadLocations;
        public Command LoadItemsCommand { get; set; }
        public Command ToolbarItemCommand { get; set; }
        public MyViewModel()
        {
            Location = new Location { Name = "Default", Filter = "Default" };
            LoadItemsCommand = new Command(ExecuteLoadItemsCommand);
            ToolbarItemCommand = new Command(SetLocation);
            AsyncCreateListProcesses();
            AsyncCreateListLocations();
        }
        void CreateListProcesses()
        {
            downloadProcesses = new DownloadProcesses();
            ProcessList = downloadProcesses.DownloadJSON().OrderByDescending(x => DateTime.Parse(x.Datum)).ThenByDescending(x => DateTime.Parse(x.Zeit)).ToList();
        }
        void CreateListLocations()
        {
            downloadLocations = new DownloadLocations();
            LocationList = downloadLocations.DownloadJSON();
            //LocationList = downloadLocations.DownloadJSON().OrderBy(x => x.Name).ToList();            
        }
        async void SetLocation()
        {
            var selectedOptionDesc = await this.userDialogs.ActionSheetAsync("MyTitle", "MyCancelButtonText", null, null, this.LocationList.Select(l => l.Name).ToArray());
            if (string.IsNullOrEmpty(selectedOptionDesc))
                return;

            var selectedOption = this.LocationList.FirstOrDefault(l => l.Name == selectedOptionDesc);
            if (selectedOption == null)
                return;

            Xamarin.Forms.Device.BeginInvokeOnMainThread(() => this.Location = selectedOption);
        }
        public Task AsyncCreateListProcesses()
        {
            return Task.Run(() => CreateListProcesses());
        }
        public Task AsyncCreateListLocations()
        {
            return Task.Run(() => CreateListLocations());
        }        
        async void ExecuteLoadItemsCommand()
        {
            if (IsBusy)
                return;

            IsBusy = true;

            try
            {
                await AsyncCreateListProcesses();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
            finally
            {
                IsBusy = false;
            }
        }

        private List<Process> _processList;
        public List<Process> ProcessList
        {
            get => _processList;
            set => SetValue(ref _processList, value);
        }
        private List<Location> _locationList;
        public List<Location> LocationList
        {
            get => _locationList;
            set => SetValue(ref _locationList, value);
        }
        private Location _location;
        public Location Location
        {
            get => _location;
            set
            {
                if (value != null)
                {
                    SetValue(ref _location, value);
                } 
            }
        }
    }

}

Ответы [ 2 ]

0 голосов
/ 06 декабря 2018

Это не выпадающий список, но вы также можете просто использовать ActionSheet (если вы не знали об этом).Я просто предлагаю это, потому что это очень просто и надежно, я понимаю, что это не так красиво, как выпадающий список (но он также может быть красивее, чем выпадающий список).

0 голосов
/ 06 декабря 2018

Я бы порекомендовал вам использовать Acr.UserDialogs , он действительно прост в использовании и позволяет выполнять настройку.

Для того, чтобы сделать то, что вы хотите, вы должны установить пакет, инициализироватьэто в вашей основной деятельности вашего проекта Android:

UserDialogs.Init(() => (Activity)Forms.Context)

введите ваши IUserDialogs в ваш ViewModel:

private IUserDialogs userDialogs;

public MyViewModel(IUserDialogs userDialogs)
{
    this.userDialogs = userDialogs;
}

и позвоните:

var selectedOptionDesc = await this.userDialogs.ActionSheetAsync("MyTitle", "MyCancelButtonText", null, null, this.LocationList.Select(l => l.Description).ToArray());
if (string.IsNullOrEmpty(selectedOptionDesc))
    return;

var selectedOption = this.LocationList.FirstOrDefault(l => l.Description == selectedOptionDesc);
if (selectedOption == null)
    return;

Xamarin.Forms.Device.BeginInvokeOnMainThread(() => this.Location = selectedOption);

Еслиу вас нет механизма внедрения зависимости, тогда вы можете заменить this.userDialogs.ActionSheetAsync(...) на:

UserDialogs.Instance.ActionSheetAsync(...)

Если вы все еще хотите использовать свою библиотеку, возможно, она не обновляет ваш вид, потому что вы не устанавливаетеLocation свойство в MainThread, поэтому вам нужно будет обернуть этот набор в Xamarin.Forms.Device.BeginInvokeOnMainThread(() => ...);, чтобы сделать это в MainThread, таким образом, ваш View получит уведомление об изменении.

HIH

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