Я пытаюсь установить связь между двумя наблюдаемыми коллекциями: Вехи, Категории.
В модели «Milestone» у меня есть свойство «SelectedCategory».
public Category SelectedCategory
{
get => selectedCategory;
set
{
if (selectedCategory != value)
{
selectedCategory = value;
OnPropertyChanged(nameof(SelectedCategory));
}
}
}
И я выбираю его в коде программной части для каждой вехи:
foreach (var m in Milestones)
{
m.SelectedCategory = Categories.FirstOrDefault(c => c.IdCategory == m.IdCategory);
}
Однако проблема в том, что когда я пытаюсь предварительно выбрать эту категорию в своем селекторе, ничего не выбрано заранее. После проверки всего кода я почти уверен, что проблема связана с XAML:
<CollectionView Grid.Row = "1" Margin = "25,10,0,0" ItemsSource = "{Binding Milestones}" VerticalOptions = "FillAndExpand">
<CollectionView.ItemTemplate>
<DataTemplate>
<Picker Grid.Column = "2"
ItemsSource = "{Binding Path=BindingContext.Categories, Source = {RelativeSource AncestorType = {x:Type local:ModifyProjectPage}}}"
ItemDisplayBinding = "{Binding CategoryName}"
SelectedItem = "{Binding SelectedCategory, Mode=TwoWay}" />
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
Кстати, привязка работает, я вижу все названия категорий и когда пытаюсь сделать это с помощью ярлыка, все работает отлично. И в консоли нет ошибки
<Label Text = "{Binding SelectedCategory.CategoryName}" />
Привязка не работает без Source = {RelativeSource AncestorType = {x:Type local:ModifyProjectPage}}}
:
<Picker Grid.Column = "2"
ItemsSource = "{Binding Categories}"
ItemDisplayBinding = "{Binding CategoryName}"
SelectedItem = "{Binding SelectedCategory, Mode=TwoWay}" />
Я столкнулся с аналогичной проблемой, я думаю, она связана с тем, как реализован Picker: каким-то образом код не получает ваш SelectedItem как член ObservableCollection и просто не может найти его в коллекции. Обходной путь, который я обычно использовал, заключался в том, чтобы не устанавливать SelectedItem, а вместо этого устанавливать SelectedIndex. Посмотрите этот вопрос, я тогда был на Мауи довольно новичком, но думаю, это может вам помочь.
Код привязки выглядит хорошо. Элемент управления Picker
размещается в DataTemplate, а свойство ItemsSource
привязывается к Categories
во ViewModel. Таким образом, вы можете использовать Относительные привязки для ItemsSource
из Picker
.
Другая причина, по которой я считаю, что это не проблема привязки, заключается в том, что если я установлю небольшую задержку, элемент PreSelected Picker будет отображаться успешно.
protected async override void OnAppearing()
{
base.OnAppearing();
await Task.Delay(50);
foreach (var m in viewModel.Milestones)
{
m.SelectedCategory = viewModel.Categories.FirstOrDefault(c => c.IdCategory == m.IdCategory);
}
}
Однако это не очень хорошее решение. Я также могу воспроизвести эту проблему, и вы можете рассмотреть возможность поднять проблему на Github.
Это работает, но, как вы сказали, это не очень хорошее решение, я нашел другие подобные проблемы на GitHub Мауи. К сожалению, проблема уже упоминалась год назад и до сих пор не устранена.
Да, это просто обходной путь. Иногда использование задержки может привести к небольшому замедлению. И то, какую задержку выставлять, также зависит от производительности разных устройств. В случае известной проблемы с MAUI рекомендуется отслеживать ее и напрямую связываться с нашими инженерами, чтобы сообщить им о ваших проблемах и потребностях.
Использование SelectedIndex тоже не работает. Я также попробовал установить
SelectedIndex = "1"
, но элементы тоже не выбраны.