#listview #xamarin
#listview #xamarin
Вопрос:
С помощью Xamarin.С помощью MVVM у меня формируется ListView историй с названием истории, категориями историй и всплывающим окном (кнопка). При нажатии на всплывающую кнопку появляется всплывающее окно, в котором пользователь может выбрать различные категории для истории. И когда пользователь выбирает разные категории, метка StoryCategories должна обновляться всеми выбранными категориями (через запятую). Но я не могу понять, как найти и обновить метку StoryCategories, с которой была нажата всплывающая кнопка?
Я разрабатываю .net mvc последние 8 лет, и мне всегда удавалось найти ответ на свои вопросы здесь, в StackOverflow (спасибо!), Но по какой-то причине я не могу найти ответ на этот вопрос.
Я надеюсь, вы сможете помочь! 🙂
Всплывающее окно представляет собой Rg.Плагины.Всплывающее окно, и я использую MvvmHelpers от Джеймса Монтеманьо.
Модель
public class Story : ObservableObject
{
string name;
public string Name
{
get { return name; }
set { SetProperty(ref name, value); }
}
string categories;
public string Categories
{
get { return categories; }
set { SetProperty(ref categories, value); }
}
}
ViewModel
public class StoriesViewModel : BaseViewModel
{
public ObservableCollection<Story> Stories { get; set; }
public StoriesViewModel()
{
Stories = new ObservableCollection<Story>();
Stories.Add(new Story { Name = "Hitchhiker's Guide to the Galaxy", Categories = "a, b" });
Stories.Add(new Story { Name = "The Restaurant at the End of the Universe", Categories = "b, c, y" });
Stories.Add(new Story { Name = "Life, the Universe and Everything", Categories = "e" });
Stories.Add(new Story { Name = "So Long, and Thanks for All the Fish", Categories = "a, c, e" });
}
public ICommand OpenPopupCommand
{
get
{
return new Command<Story>((x) =>
{
Debug.WriteLine("Name: " x.Name);
});
}
}
}
Вид:
<ListView ItemsSource="{Binding Stories}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label Text="{Binding Name}" />
<Label Text="{Binding Categories} "/>
<Button Text="Click" Command="{ Binding Path=BindingContext.OpenPopupCommand, Source={ x:Reference Stories } }" CommandParameter="{ Binding . }" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Комментарии:
1. вы спрашиваете, как ваша страница может узнать, что нужно обновить, когда всплывающее окно закрыто? Вы могли бы использовать MessagingCenter для передачи сообщения из всплывающего окна на страницу, когда всплывающее окно закрывается. Или ваше всплывающее окно может отображать событие, на которое подписана ваша страница.
2. @Jason Поправьте меня, если я здесь ошибаюсь, но не было бы лучшим подходом для этого передать
Action
в качестве параметра конструктора, а затем вызвать это действие со всплывающей страницы, что-то вроде обратного вызова?3. @Jason точно да (или предпочтительно обновлять его по мере выбора пользователем категории). Я загляну в MessagingCenter.
4. @G.hakim Благодарю вас за предложение. Никогда не слышал о параметрах конструктора. Я ищу несколько примеров 🙂
Ответ №1:
Если вы используете событие clicked, вы могли бы сделать что-то вроде этого, я только предполагаю название класса, который вы используете, но вы должны его получить:
var story = ((Button)sender).BindingContext as Story;
Ответ №2:
Если вы используете шаблон MVVM, попробуйте следующее:
<ListView x:Name="Stories">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label Text="{Binding StoryName}" />
<Label Text="{Binding StoryCategories} "/>
<Button Command="{ Binding Path=BindingContext.OpenPopupCommand, Source={ x:Reference Stories } }" CommandParameter="{ Binding . }" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
В модели представления
public ICommand OpenPopupCommand
{
get
{
return new Command<Story>((x) =>
{
// x is Story type
});
}
}
Комментарии:
1. Когда я делаю это, я получаю исключение: Необработанное исключение: Xamarin. Forms.Xaml.XamlParseException: Позиция 14:50. Не удается найти объект, на который ссылается
Stories
. Я обновил вопрос с помощью моей модели, viewmodel и view. Может быть, я сделал что-то не так? И спасибо за предложение 🙂2. Вы удалили имя списка. С вашим обновлением определение списка будет
<ListView x:Name="stories" ItemsSource="{Binding Stories}">
(проверьте параметр x:Name), а затем в команде измените на... Source={ x:Reference stories } ...
Ответ №3:
Способ, которым я исправлял это в прошлом, заключается в передаче всей модели просмотра страницы истории на всплывающую страницу, а затем, когда категория изменяется, вы можете обновить метку на странице истории из модели просмотра всплывающей страницы. Я не знаю, лучшее ли это решение, но оно работает.