我创建了一个Windows Phone 8.1运行时应用程序。
我正在使用ListView控件。
我希望替换每个背景行颜色。
搜索后,我发现此链接a previous answer。
但这会给标记带来错误。一方面,没有“AlternationCount”#39;属性。我假设这是因为它不是SilverLight而是RT?
如果有人可以给我发送链接,因为我正在寻找一个简单的例子。更好的是一个简单的代码示例。
答案 0 :(得分:6)
我知道这个问题已经有了一些很好的答案,但我只想提出一个更多的想法,我认为这个想法有点难以实现,但更容易使用。
此解决方案需要ListView
ItemContainerStyleSelector
的帮助和行为SDK(XAML)的Behavior
。
基本上,我创建的AlternatingColorItemContainerStyleSelector
行为允许您指定两种SolidColorBrush
颜色。它概括了使用两个不同的ItemContainerStyleSelector
创建Style
以及为每个SolidColorBrush
分配相应的Style
的逻辑。
一旦你有了这种行为,使用它非常简单 - 我只需要将它拖放到Expression Blend中的ListView
并指定两种颜色即可!
这是行为。
namespace Behaviors
{
public class AlternatingColorItemContainerStyleSelector : StyleSelector
{
private Style _oddStyle = new Style { TargetType = typeof(ListViewItem) }, _evenStyle = new Style { TargetType = typeof(ListViewItem) };
public Style OddStyle { get { return _oddStyle; } }
public Style EvenStyle { get { return _evenStyle; } }
protected override Style SelectStyleCore(object item, DependencyObject container)
{
var listViewItem = (ListViewItem)container;
var listView = GetParent<ListView>(listViewItem);
var index = listView.IndexFromContainer(listViewItem);
if (index % 2 == 0)
{
return this.EvenStyle;
}
else
{
return this.OddStyle;
}
}
public static T GetParent<T>(DependencyObject child) where T : DependencyObject
{
while (!(child is T))
{
child = VisualTreeHelper.GetParent(child);
}
return (T)child;
}
}
public class ListViewAlternatingColorBehavior : DependencyObject, IBehavior
{
public DependencyObject AssociatedObject { get; set; }
public Style SharedItemContainerStyle { get; set; }
#region colors dp
public SolidColorBrush OddBrush
{
get { return (SolidColorBrush)GetValue(OddBrushProperty); }
set { SetValue(OddBrushProperty, value); }
}
public static readonly DependencyProperty OddBrushProperty =
DependencyProperty.Register("OddBrush", typeof(SolidColorBrush), typeof(ListViewAlternatingColorBehavior), new PropertyMetadata(null));
public SolidColorBrush EvenBrush
{
get { return (SolidColorBrush)GetValue(EvenBrushProperty); }
set { SetValue(EvenBrushProperty, value); }
}
public static readonly DependencyProperty EvenBrushProperty =
DependencyProperty.Register("EvenBrush", typeof(SolidColorBrush), typeof(ListViewAlternatingColorBehavior), new PropertyMetadata(null));
#endregion
public void Attach(DependencyObject associatedObject)
{
this.AssociatedObject = associatedObject;
this.ApplyItemContainerStyleSelectors();
}
private void ApplyItemContainerStyleSelectors()
{
var itemContainerStyleSelector = new AlternatingColorItemContainerStyleSelector();
if (this.SharedItemContainerStyle != null)
{
itemContainerStyleSelector.OddStyle.BasedOn = this.SharedItemContainerStyle;
itemContainerStyleSelector.EvenStyle.BasedOn = this.SharedItemContainerStyle;
}
itemContainerStyleSelector.OddStyle.Setters.Add(new Setter { Property = Control.BackgroundProperty, Value = this.OddBrush });
itemContainerStyleSelector.EvenStyle.Setters.Add(new Setter { Property = Control.BackgroundProperty, Value = this.EvenBrush });
var listView = (ListView)this.AssociatedObject;
listView.ItemContainerStyleSelector = itemContainerStyleSelector;
}
public void Detach()
{
}
}
}
有一点需要注意的是,删除商品不会更新所有其他商品&#39;颜色(仅仅因为其他项目的SelectStyleCore
未被调用),添加项目将会。但在你的情况下,这应该足够了。
答案 1 :(得分:5)
我的建议是将 Converter 类与其他 DependencyProperties 一起使用。初始化转换器时,您可以定义它将引用的项集合以及背景的备用画笔列表。它可以看起来像这样:
public class AlternateConverter : DependencyObject, IValueConverter
{
public List<SolidColorBrush> AlternateBrushes
{
get { return (List<SolidColorBrush>)GetValue(AlternateBrushesProperty); }
set { SetValue(AlternateBrushesProperty, value); }
}
public static readonly DependencyProperty AlternateBrushesProperty =
DependencyProperty.Register("AlternateBrushes", typeof(List<SolidColorBrush>),
typeof(AlternateConverter), new PropertyMetadata(new List<SolidColorBrush>()));
public object CurrentList
{
get { return GetValue(CurrentListProperty); }
set { SetValue(CurrentListProperty, value); }
}
public static readonly DependencyProperty CurrentListProperty =
DependencyProperty.Register("CurrentList", typeof(object),
typeof(AlternateConverter), new PropertyMetadata(null));
public object Convert(object value, Type targetType, object parameter, string language)
{ return AlternateBrushes[(CurrentList as IList).IndexOf(value) % AlternateBrushes.Count]; }
public object ConvertBack(object value, Type targetType, object parameter, string language)
{ throw new NotImplementedException(); }
}
一旦定义了它并创建备用画笔列表:
// somewhere in your DataContext
private List<SolidColorBrush> brushes = new List<SolidColorBrush> { new SolidColorBrush(Colors.Red), new SolidColorBrush(Colors.Blue) };
public List<SolidColorBrush> Brushes { get { return brushes; } }
你可以像这样使用它:
<ListView x:Name="myList" ItemsSource={Binding MyItems}>
<ListView.Resources>
<local:AlternateConverter CurrentList="{Binding ElementName=myList, Path=ItemsSource}"
AlternateBrushes="{Binding Brushes}"
x:Key="AlternateConverter"/>
</ListView.Resources>
<ListView.ItemTemplate>
<DataTemplate>
<Border Background="{Binding Converter={StaticResource AlternateConverter}}">
<!-- your itemtemplate -->
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
此解决方案应该可行,但是当您拥有IList值类型时可能会出现问题。此处也不应该是延迟创建的问题,因为它直接从列表中检索索引。
答案 2 :(得分:2)
WPF是唯一支持&#34; AlternationCount&#34; - Windows Phone,Silverlight和RT都没有。
您可能会发现最简单的解决方案就是添加一个&#34;索引&#34;或者&#34; IsOdd&#34;您的行模型的属性。您可以绑定到该属性,使用转换器根据索引返回适当的画笔/颜色。
一种更简单的方法是绑定到使用静态变量跟踪索引的转换器,如下所示。但是,如果您使用项目虚拟化(除非您只有少数项目,您可能会这样做),这种方法会出现故障:UI元素的延迟创建会导致索引无序分配,并且您结束连续的行显示相同的颜色。
<Border Background="{Binding Converter={StaticResource AlternatingIndexConverter}}">
public class AlternatingIndexConverter : IValueConverter
{
private static int _index;
public Brush Even { get; set; }
public Brush Odd { get; set; }
public object Convert(...)
{
return (_index++ % 2 == 0 ? Even : Odd);
}
}
答案 3 :(得分:2)
对我而言,最简单的方法是:
private void ListView_ContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
{
if (args.ItemIndex%2 != 0)
{
args.ItemContainer.Background = new SolidColorBrush(Colors.Aqua);
}
else
{
args.ItemContainer.Background = new SolidColorBrush(Colors.White);
}
}
只需将您连接到ListView的ContainerContentChanging-Event即可。我不知道你的名单是否合适,但正常情况下它的效果非常好。
您甚至可以实现自己的ListView,因此您可以随意使用它。使用正确的属性,您还可以在xaml文件中编辑它。例如,#FFFF0000(ARGB)。
public class BackgroundAlternatingListView : ListView
{
private Color _startColor = Colors.White;
private Color _secondColor = new Color { A = 255, R = 198, G = 198, B = 198 };
public Color StartColor
{
get { return _startColor; }
set { _startColor = value; }
}
public Color SecondColor
{
get { return _secondColor; }
set { _secondColor = value; }
}
public BackgroundAlternatingListView()
{
ContainerContentChanging += BackgroundAlternatingListView_ContainerContentChanging;
}
void BackgroundAlternatingListView_ContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
{
if (args.ItemIndex % 2 != 0)
{
args.ItemContainer.Background = new SolidColorBrush(_secondColor);
}
else
{
args.ItemContainer.Background = new SolidColorBrush(_startColor);
}
}
}
答案 4 :(得分:0)
感谢您的回复 - 非常感谢。我有另一个我想提出的解决方案,我将其发布在此处供人们评论。
lvwPremises.Items.Clear();
bool toggle = false;
foreach (Premise premise in Shared.Premises)
{
ListViewItem item = new ListViewItem();
item.Content = premise.PremiseName;
if (toggle)
{
item.Background = new SolidColorBrush(Windows.UI.Color.FromArgb(255, 223, 240, 216));
}
else
{
item.Background = new SolidColorBrush(Windows.UI.Color.FromArgb(255, 208, 233, 198));
}
lvwPremises.Items.Add(item);
toggle = !toggle;
}
如果您愿意,您可以随时使用代码,但是您的解决方案不是那么通用,在更改收集时必须始终运行并且可能有其他问题。我把这个评论作为你的答案的编辑,因此上面的代码可能会简化,它看起来像这样(在答案中看起来更好):
private void ColorBackgrounds(ListView list, IList<SolidColorBrush> backgrounds)
{
for (int i = 0; i < list.Items.Count; i++)
(list.ContainerFromIndex(i) as ListViewItem).Background = backgrounds[i % backgrounds.Count];
}