我尝试在{RelativeSource PreviousData}
中使用ListBox.ItemTemplate
,但它运行正常。
但是,当使用下面提供的特定代码时,当向下滚动几次并且Rectangle
的某些缺失时,绑定会停止工作。
即使使用单个DataTrigger
,问题也会重现,但当ListBox.Height
超过 178 时,它会不重建。
<Window
x:Class="PreviousDataBindingWheelIssue.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PreviousDataBindingWheelIssue"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="PreviousData Issue"
d:DataContext="{d:DesignInstance Type=local:MyModel}"
SizeToContent="WidthAndHeight"
mc:Ignorable="d">
<StackPanel>
<!-- Height must be less or equal to 178 -->
<ListBox
Width="300"
Height="178"
HorizontalContentAlignment="Stretch"
ItemsSource="{Binding MyData}">
<ListBox.ItemTemplate>
<DataTemplate>
<DockPanel Background="#FFFFFFED">
<Rectangle
Height="2"
Margin="0"
DockPanel.Dock="Top">
<Rectangle.Style>
<Style TargetType="Rectangle">
<Setter Property="Fill" Value="#FF63605C" />
<Style.Triggers>
<!--
Hide our magnificent separator if this is the first item on the list
see http://stackoverflow.com/a/22705507/426315
but, it seems to have some issues when using mouse wheel
some of the rows does NOT have the rectangle even when PreviousData SHOULD not be null
-->
<DataTrigger Binding="{Binding RelativeSource={RelativeSource PreviousData}}" Value="{x:Null}">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
<DataTrigger Binding="{Binding}" Value="Fun Item">
<Setter Property="Fill" Value="SpringGreen" />
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
<TextBlock
Margin="5,7,5,7"
VerticalAlignment="Center"
FontSize="12"
Text="{Binding}" />
</DockPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</Window>
using System.Windows;
namespace PreviousDataBindingWheelIssue
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MyModel();
}
}
}
using System.Collections.ObjectModel;
namespace PreviousDataBindingWheelIssue
{
public class MyModel
{
public ObservableCollection<string> MyData { get; set; }
public MyModel()
{
MyData = new ObservableCollection<string>()
{
"Lorem ipsum dolor", "sit amet, consectetur", "adipiscing elit. Sed",
"Fun Item",
"rhoncus leo convallis", "pulvinar tellus at",
"Fun Item",
"porta metus. Mauris", "sed mauris quis", "neque congue semper",
"Fun Item",
"vitae non leo", "Donec aliquet feugiat", "massa vitae luctus",
"Fun Item",
"Duis pharetra velit", "et lorem blandit"
};
}
}
}
答案 0 :(得分:1)
由于PreviousData
绑定在虚拟化方面不可靠,您可以通过在VirtualizingPanel.IsVirtualizing="False"
上设置ListBox
来禁用虚拟化,或者使绑定虚拟化准备就绪。
处理此类问题的一种方法是在我的示例代码中创建自定义列表框(ListBox2
),覆盖PrepareContainerForItemOverride
并设置一些可用于进一步操作的属性。为此,我创建了一个附加属性ItemIndex
。
public class ListBox2 : ListBox
{
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
base.PrepareContainerForItemOverride(element, item);
SetItemIndex(element, ItemContainerGenerator.IndexFromContainer(element));
}
// helper attached property to indicate the index of listbox items
public static int GetItemIndex(DependencyObject obj)
{
return (int)obj.GetValue(ItemIndexProperty);
}
protected static void SetItemIndex(DependencyObject obj, int value)
{
obj.SetValue(ItemIndexPropertyKey, value);
}
private static readonly DependencyPropertyKey ItemIndexPropertyKey =
DependencyProperty.RegisterAttachedReadOnly("ItemIndex", typeof(int), typeof(ListBox2), new PropertyMetadata(-1));
public static readonly DependencyProperty ItemIndexProperty = ItemIndexPropertyKey.DependencyProperty;
}
然后更改xaml以使用ListBox2
并依赖ItemIndex
代替PreviousData
:
<local:ListBox2
Width="300"
Height="178"
HorizontalContentAlignment="Stretch"
ItemsSource="{Binding MyData}">
<local:ListBox2.ItemTemplate>
<DataTemplate>
<DockPanel Background="#FFFFFFED">
<Rectangle
Height="2"
Margin="0"
DockPanel.Dock="Top">
<Rectangle.Style>
<Style TargetType="Rectangle">
<Setter Property="Fill" Value="#FF63605C" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=(local:ListBox2.ItemIndex),RelativeSource={RelativeSource AncestorType=ListBoxItem}}" Value="0">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
<DataTrigger Binding="{Binding}" Value="Fun Item">
<Setter Property="Fill" Value="SpringGreen" />
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
<TextBlock
Margin="5,7,5,7"
VerticalAlignment="Center"
FontSize="12"
Text="{Binding}" />
</DockPanel>
</DataTemplate>
</local:ListBox2.ItemTemplate>
</local:ListBox2>