Как получить представление списка форм Xamarin для сброса настраиваемой ячейки представления после удаления на Android?
Я реализую функцию удаления объекта с помощью пользовательской ячейки представления и средства визуализации. У меня есть представление списка, например, так:
и когда проведено, кнопка показывается, как показано ниже
Однако после нажатия кнопки удаления (которая успешно удаляет элемент из списка) в ячейке просмотра, которая переместилась в позицию удаления, все еще отображается кнопка удаления:
У кого-нибудь есть идеи, как это предотвратить? Мой пользовательский рендерер просто выставляет события OnFling() и OnScroll().
Я также попробовал аналогичную вещь, используя формы Pan Gesture Recogniser Xamarin, и столкнулся с той же проблемой.
РЕДАКТИРОВАТЬ 1: Добавлены фрагменты кода
Пользовательский вид ячейки xaml
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="SwipeViewCell" xmlns:local="CustomControls">
<Grid x:Name="SwipeViewCellGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70*"/>
<ColumnDefinition Width="30*"/>
</Grid.ColumnDefinitions>
<StackLayout x:Name="HiddenContainer" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Grid.Column="1"/>
<local:GestureStackLayout x:Name="SwipeContainer" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Grid.ColumnSpan="2" Grid.Column="0"/>
</Grid>
Custom View Cell.cs:
public partial class SwipeViewCell : ViewCell
{
private View _swipeContent;
private View _hiddenContent;
public SwipeViewCell()
{
InitializeComponent();
SwipeContainer.SwipeLeft += SwipeContainer_SwipeLeft;
SwipeContainer.SwipeRight += SwipeContainer_SwipeRight;
}
public View SwipeContent
{
get
{
return _swipeContent;
}
set
{
_swipeContent = value;
SwipeContainer.Children.Add(SwipeContent);
OnPropertyChanged();
}
}
public View HiddenContent
{
get
{
return _hiddenContent;
}
set
{
_hiddenContent = value;
HiddenContainer.Children.Add(HiddenContent);
OnPropertyChanged();
}
}
private void SwipeContainer_SwipeRight(object sender, EventArgs e)
{
SwipeContainer.TranslateTo(SwipeContainer.X, 0, 250, Easing.Linear);
}
private void SwipeContainer_SwipeLeft(object sender, EventArgs e)
{
SwipeContainer.TranslateTo(SwipeContainer.X - HiddenContainer.Width, 0, 250, Easing.Linear);
}
}
Посмотреть модель:
public class ViewModel
{
private ObservableCollection<string> _data;
public ViewModel()
{
Data = new ObservableCollection<string>();
Data.Add("a");
Data.Add("c");
Data.Add("b");
}
public ObservableCollection<string> Data
{
get { return _data; }
set
{
_data= value;
OnPropertyChanged();
}
}
public ICommand Delete
{
get
{
return new Command((e) =>
{
_data.Remove(e as string);
Data = _data
});
}
}
}
XAML:
<ListView ItemsSource="{Binding Data}" x:Name="Model" HorizontalOptions="FillAndExpand" IsVisible="True" VerticalOptions="FillAndExpand" SeparatorVisibility="Default" SeparatorColor="Black">
<CustomControls:MultiListView.ItemTemplate>
<DataTemplate>
<CustomControls:SwipeViewCell x:Name="Item">
<CustomControls:SwipeViewCell.SwipeContent>
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="White">
<Label Text="{Binding }"/>
</StackLayout>
</CustomControls:SwipeViewCell.SwipeContent>
<CustomControls:SwipeViewCell.HiddenContent>
<Button Text="Delete" Command="{Binding Delete}" BindingContext="{Binding Source={x:Reference Model}, Path=BindingContext}" CommandParameter="{Binding Source={x:Reference Item}, Path=BindingContext}" BackgroundColor="Red"></Button>
</CustomControls:SwipeViewCell.HiddenContent>
</CustomControls:SwipeViewCell>
</DataTemplate>
<ListView.ItemTemplate>
<ListView>
1 ответ
На следующем полном примере, как вы можете это сделать, он работает нормально для меня:
1- Добавление класса, содержащего число, отображаемое в списке
public class NumberClass
{
public string Number{ get; set; }
}
2-попробуй использовать ObservableCollection
за NumberClass
в дальнейшем:
public class NumberClassList : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public System.Collections.ObjectModel.ObservableCollection<NumberClass> _items;
public ObservableCollection<NumberClass> Items
{
get { return _items; }
set { _items = value; OnPropertyChanged("Items"); }
}
protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged == null)
return;
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public SerialClassList(List<NumberClass> itemList)
{
Items = new ObservableCollection<NumberClass>();
foreach (NumberClassitm in itemList)
{
Items.Add(itm);
}
}
}
3-поставить свой список номеров на List<NumberClass>
public List<NumberClass> allItems;
4-Используйте NumberClassList следующим образом:
NumberClassList items;
items = new NumberClassList(allItems);
5-установить пункт Источник для вашего ListView
в дальнейшем:
ItemsSource = items.Items;
6-Создать DataTemplate
для тебя ListView
следующим образом: Примечания: кнопка "Удалить" и номер имеют одинаковую привязку
DataTemplate dt = new DataTemplate(() =>
{
var Number = new Label
{
TextColor=Color.Black,
FontAttributes=FontAttributes.Bold,
HorizontalOptions = LayoutOptions.StartAndExpand
};
Number.SetBinding(Label.TextProperty, new Binding("Number"));
var Deletebutton = new Button { Text = "Delete", HorizontalOptions = LayoutOptions.StartAndExpand };
Deletebutton.SetBinding(Button.CommandParameterProperty, new Binding("Number"));
Deletebutton.Clicked += DeleteSerial;
return new ViewCell
{
View = new StackLayout
{
Orientation = StackOrientation.Horizontal,
VerticalOptions = LayoutOptions.FillAndExpand,
Children =
{
Number,
Deletebutton
}
}
};
});
YourListView.ItemTemplate = dt;
7-это реализация кнопки Удалить:
public void DeleteSerial(object sender,EventArgs e)
{
var item = (Xamarin.Forms.Button)sender;
SerialClass listitem = (from itm in items.Items
where itm.Number == item.CommandParameter.ToString()
select itm)
.FirstOrDefault<SerialClass>();
items.Items.Remove(listitem);
}