删除一行后更新 ListView DataTemplate
Update ListView DataTemplate after removing one row
我在使用 ListView 时遇到了意外情况。我有这个 ListView,其中的行根据其奇偶性具有背景颜色。在我从绑定集合中删除一个元素之前,它工作得很好,然后具有相同背景颜色的两行一起出现。这是我的代码:
<ResourceDictionary>
<DataTemplate x:Key="EvenIndexDataTemplate">
<ViewCell>
<Grid BackgroundColor="LightGray"">
<!-- my content here -->
</Grid>
</ViewCell>
</DataTemplate>
<DataTemplate x:Key="OddIndexDataTemplate">
<ViewCell>
<Grid BackgroundColor="White"">
<!-- my content here -->
</Grid>
</ViewCell>
</DataTemplate>
<datatemp:EvenOddTemplateSelector x:Key="MyDataTemplate"
EvenTemplate="{StaticResource EvenIndexDataTemplate}"
OddTemplate="{StaticResource OddIndexDataTemplate}" />
</ResourceDictionary>
<ContentPage.Content>
<!-- something here -->
<ListView ItemsSource="{Binding ItemsSource}"
ItemTemplate="{StaticResource ItemTemplateResource}" />
<!-- something else here -->
</ContentPage.Content>
我的 DataTemplateSelector class:
public class EvenOddTemplateSelector : DataTemplateSelector
{
public DataTemplate EvenTemplate { get; set; }
public DataTemplate OddTemplate { get; set; }
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
var itemsView = (ListView)container;
return ((IList)itemsView.ItemsSource).IndexOf(item) % 2 == 0 ? EvenTemplate : OddTemplate;
}
我想得到的是在删除项目后保留具有不同背景颜色的相邻行。此时 ItemsSource 仅被 Adding/Removing 修改。我没有尝试插入一个项目。我正在开发的这个功能不需要它。
有什么想法吗?
我刚刚解决了这个问题。这是我所做的:
我创建了 ViewCell
class 的自定义并添加了三个可绑定属性 ContainerItemsSource
、EvenBackgroundColor
和 OddBackgroundColor
,然后我覆盖了 OnBindingContextChanged()
以确保根据其在集合中的索引设置 View
背景颜色。
您可以在 github 存储库上的 new brach 上查看。
基本上思路是这样用的:
<ListView ItemsSource="{Binding YOUR_ITEMS_SOURCE}">
<ListView.ItemTemplate>
<DataTemplate>
<local:EvenOddCell ContainerItemsSource="{Binding YOUR_ITEMS_SOURCE,
Source={x:Reference YOUR_PAGE_BINDING_CONTEXT}}"
EvenBackgroundColor="AliceBlue"
OddBackgroundColor="White">
<!-- YOUR CELL CONTENT -->
</local:EvenOddCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
我的习惯EvenOddCell
:
public class EvenOddCell : ViewCell
{
public Color EvenBackgroundColor
{
get => (Color)GetValue(EvenBackgroundColorProperty);
set => SetValue(EvenBackgroundColorProperty, value);
}
public Color OddBackgroundColor
{
get => (Color)GetValue(OddBackgroundColorProperty);
set => SetValue(OddBackgroundColorProperty, value);
}
public IList ContainerItemsSource
{
get => (IList)GetValue(ContainerItemsSourceProperty);
set => SetValue(ContainerItemsSourceProperty, value);
}
public static BindableProperty EvenBackgroundColorProperty = BindableProperty.Create(
nameof(EvenBackgroundColor), typeof(Color), typeof(EvenOddCell), default(Color));
public static BindableProperty OddBackgroundColorProperty = BindableProperty.Create(
nameof(OddBackgroundColor), typeof(Color), typeof(EvenOddCell), default(Color));
public static BindableProperty ContainerItemsSourceProperty = BindableProperty.Create(
nameof(ContainerItemsSource), typeof(IList), typeof(EvenOddCell),
default(IList), propertyChanged: OnContainerItemsSourcePropertyChanged);
private static void OnContainerItemsSourcePropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
if (newValue != null && newValue is INotifyCollectionChanged)
{
((INotifyCollectionChanged)newValue).CollectionChanged += (s, e) =>
{
if (e.Action != NotifyCollectionChangedAction.Add)
{
((EvenOddCell)bindable).OnBindingContextChanged();
}
};
}
}
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
if (BindingContext != null && ContainerItemsSource is IList)
{
var idx = ContainerItemsSource.IndexOf(BindingContext);
View.BackgroundColor = idx % 2 == 0 ? EvenBackgroundColor : OddBackgroundColor;
}
}
}
我在使用 ListView 时遇到了意外情况。我有这个 ListView,其中的行根据其奇偶性具有背景颜色。在我从绑定集合中删除一个元素之前,它工作得很好,然后具有相同背景颜色的两行一起出现。这是我的代码:
<ResourceDictionary>
<DataTemplate x:Key="EvenIndexDataTemplate">
<ViewCell>
<Grid BackgroundColor="LightGray"">
<!-- my content here -->
</Grid>
</ViewCell>
</DataTemplate>
<DataTemplate x:Key="OddIndexDataTemplate">
<ViewCell>
<Grid BackgroundColor="White"">
<!-- my content here -->
</Grid>
</ViewCell>
</DataTemplate>
<datatemp:EvenOddTemplateSelector x:Key="MyDataTemplate"
EvenTemplate="{StaticResource EvenIndexDataTemplate}"
OddTemplate="{StaticResource OddIndexDataTemplate}" />
</ResourceDictionary>
<ContentPage.Content>
<!-- something here -->
<ListView ItemsSource="{Binding ItemsSource}"
ItemTemplate="{StaticResource ItemTemplateResource}" />
<!-- something else here -->
</ContentPage.Content>
我的 DataTemplateSelector class:
public class EvenOddTemplateSelector : DataTemplateSelector
{
public DataTemplate EvenTemplate { get; set; }
public DataTemplate OddTemplate { get; set; }
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
var itemsView = (ListView)container;
return ((IList)itemsView.ItemsSource).IndexOf(item) % 2 == 0 ? EvenTemplate : OddTemplate;
}
我想得到的是在删除项目后保留具有不同背景颜色的相邻行。此时 ItemsSource 仅被 Adding/Removing 修改。我没有尝试插入一个项目。我正在开发的这个功能不需要它。
有什么想法吗?
我刚刚解决了这个问题。这是我所做的:
我创建了 ViewCell
class 的自定义并添加了三个可绑定属性 ContainerItemsSource
、EvenBackgroundColor
和 OddBackgroundColor
,然后我覆盖了 OnBindingContextChanged()
以确保根据其在集合中的索引设置 View
背景颜色。
您可以在 github 存储库上的 new brach 上查看。
基本上思路是这样用的:
<ListView ItemsSource="{Binding YOUR_ITEMS_SOURCE}">
<ListView.ItemTemplate>
<DataTemplate>
<local:EvenOddCell ContainerItemsSource="{Binding YOUR_ITEMS_SOURCE,
Source={x:Reference YOUR_PAGE_BINDING_CONTEXT}}"
EvenBackgroundColor="AliceBlue"
OddBackgroundColor="White">
<!-- YOUR CELL CONTENT -->
</local:EvenOddCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
我的习惯EvenOddCell
:
public class EvenOddCell : ViewCell
{
public Color EvenBackgroundColor
{
get => (Color)GetValue(EvenBackgroundColorProperty);
set => SetValue(EvenBackgroundColorProperty, value);
}
public Color OddBackgroundColor
{
get => (Color)GetValue(OddBackgroundColorProperty);
set => SetValue(OddBackgroundColorProperty, value);
}
public IList ContainerItemsSource
{
get => (IList)GetValue(ContainerItemsSourceProperty);
set => SetValue(ContainerItemsSourceProperty, value);
}
public static BindableProperty EvenBackgroundColorProperty = BindableProperty.Create(
nameof(EvenBackgroundColor), typeof(Color), typeof(EvenOddCell), default(Color));
public static BindableProperty OddBackgroundColorProperty = BindableProperty.Create(
nameof(OddBackgroundColor), typeof(Color), typeof(EvenOddCell), default(Color));
public static BindableProperty ContainerItemsSourceProperty = BindableProperty.Create(
nameof(ContainerItemsSource), typeof(IList), typeof(EvenOddCell),
default(IList), propertyChanged: OnContainerItemsSourcePropertyChanged);
private static void OnContainerItemsSourcePropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
if (newValue != null && newValue is INotifyCollectionChanged)
{
((INotifyCollectionChanged)newValue).CollectionChanged += (s, e) =>
{
if (e.Action != NotifyCollectionChangedAction.Add)
{
((EvenOddCell)bindable).OnBindingContextChanged();
}
};
}
}
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
if (BindingContext != null && ContainerItemsSource is IList)
{
var idx = ContainerItemsSource.IndexOf(BindingContext);
View.BackgroundColor = idx % 2 == 0 ? EvenBackgroundColor : OddBackgroundColor;
}
}
}