У меня также есть MainViewModel, который имеет ObservableCollection BrowsingItems
В MainPage есть словарь ресурсов с DataTemplates, один из которых содержит пользовательскую TestCard и это TouchBehaviour из набора инструментов сообщества. Данные из BrowsingItems привязаны к CollectionView с помощью DataTemplateSelector, который сравнивается на основе того, является ли IBaseItem TestItem или нет.
Код: Выделить всё
Код: Выделить всё
.
.
.
.
Вторая команда предназначена для добавления новых элементов TestItem на основе имени, выбранного в другом всплывающем окне. Команда используется в привязке к другой кнопке на странице.
Код: Выделить всё
public partial class MainViewModel : ObservableObject
{
public MainViewModel()
{
BrowsingItems = [];
}
public ObservableCollection BrowsingItems { get; private set; }
void Sort()
{
var temp = BrowsingItems.OrderByDescending(x => x is FolderItem).ToList();
BrowsingItems.Clear();
foreach (var e in temp) BrowsingItems.Add(e);
}
[RelayCommand]
async void AddTest()
{
var popup = new CreateBrowsingItemPopup();
var name = await Application.Current.MainPage.ShowPopupAsync(popup);
if (name != null)
{
BrowsingItems.Add(new TestItem() { Name = (string)name, QuestionsAmount = 0, QuestionsAnswered = 0, Random = false });
Sort();
}
}
int folderCount = 0;
int testCount = 0;
[RelayCommand]
async void AddFolder()
{
var popup = new CreateBrowsingItemPopup();
var name = await Application.Current.MainPage.ShowPopupAsync(popup);
if (name != null)
{
BrowsingItems.Add(new FolderItem() { Name = (string)name });
Sort();
}
}
[RelayCommand]
async void ShowTestContextPopup(TestItem testItem)
{
var popup = new TestCardContextPopup(testItem.Name);
var result = await Application.Current.MainPage.ShowPopupAsync(popup);
BrowsableCommandType? testCommand = (BrowsableCommandType?) result;
if (testCommand == null) return;
switch (testCommand)
{
case BrowsableCommandType.DELETE:
BrowsingItems.Remove(testItem);
break;
}
}
}
Если я добавляю еще один TestItem с помощью кнопки, он добавляется с соответствующим именем.
Однако, если я удержу его, имя, отображаемое во всплывающем окне, будет относиться к предыдущему элементу TestItem.
оно также передает ту же предыдущую ссылку команде ShowTestContextPopup. p>
Есть идеи о том, как помешать ему перерабатывать старые ссылки или как обновить привязки в DataTemplate?
РЕДАКТИРОВАТЬ 1:вот TestItem.cs
Код: Выделить всё
public class TestItem : IBaseItem
{
public int ID { get; init; }
public string Name { get; init; }
public int QuestionsAmount { get; init; }
public int QuestionsAnswered { get; init; }
public bool Random { get; init; }
public double PercentageAnswered => (QuestionsAmount==0) ? 0 : (double)QuestionsAnswered / (double)QuestionsAmount;
}
Код: Выделить всё
public class BrowsingItemDataTemplateSelector : DataTemplateSelector
{
public DataTemplate? TemplateTest { get; set; }
public DataTemplate? TemplateFolder { get; set; }
protected override DataTemplate? OnSelectTemplate(object item, BindableObject container)
{
return ((IBaseItem)item is TestItem) ? TemplateTest : TemplateFolder;
}
}
Код: Выделить всё
Код: Выделить всё
TestCard.xaml.cs
ShowTestContextPopup.xaml:
Код: Выделить всё
Код: Выделить всё
public enum BrowsableCommandType { EDIT, INFO, DELETE, RESET };
public partial class TestCardContextPopup : Popup
{
public TestCardContextPopup(string name)
{
InitializeComponent();
nameLbl.Text = name;
editBttn.Clicked = new Command (() => { ReturnTestCommand(BrowsableCommandType.EDIT); });
infoBttn.Clicked = new Command(() => { ReturnTestCommand(BrowsableCommandType.INFO); });
deleteBttn.Clicked = new Command(() => { ReturnTestCommand(BrowsableCommandType.DELETE); });
resetBttn.Clicked = new Command(() => { ReturnTestCommand(BrowsableCommandType.RESET); });
}
public void ReturnTestCommand(BrowsableCommandType command)
{
Close(command);
}
}
Код: Выделить всё
public interface IBaseItem
{
public int ID { get;}
}
Код: Выделить всё
Код: Выделить всё
public partial class GoldMenuAddButton : Border
{
public GoldMenuAddButton()
{
InitializeComponent();
}
public BindableProperty ImageProperty = BindableProperty.Create(nameof(Image), typeof(ImageSource), typeof(GoldMenuAddButton)
, propertyChanged: (bindable, oldValue, newValue) =>
{
var control = bindable as GoldMenuAddButton;
control.image.Source = newValue as ImageSource;
});
public static readonly BindableProperty ClickedProperty = BindableProperty.Create(nameof(Clicked), typeof(ICommand), typeof(GoldMenuAddButton)
, propertyChanged: (bindable, oldValue, newValue) =>
{
var control = bindable as GoldMenuAddButton;
control.tapRecognizer.Command = newValue as ICommand; ;
});
public ICommand Clicked
{
get => GetValue(ClickedProperty) as ICommand;
set => SetValue(ClickedProperty, value);
}
public ImageSource Image
{
get => GetValue(ImageProperty) as ImageSource;
set => SetValue(ImageProperty, value);
}
}
v1)
- Нажмите кнопку с командой AddFolder и введите имя. например. Test1 во всплывающем окне.
- Удерживая только что созданную TestCard, отобразится всплывающее окно с Test1. Нажмите кнопку удаления.
- Повторите 1)
- Повторите 2), но имя, отображаемое во всплывающем окне, и переданная ссылка относятся к Test1. TestItem.
Подробнее здесь: https://stackoverflow.com/questions/785 ... n-net-maui