gpt4 book ai didi

wpf - 绑定(bind) {RelativeSource PreviousData} 在特定情况下会中断绑定(bind)

转载 作者:行者123 更新时间:2023-12-04 19:05:32 24 4
gpt4 key购买 nike

我尝试使用 {RelativeSource PreviousData}ListBox.ItemTemplate它工作正常。

但是,当使用下面提供的特定代码时,绑定(bind)会在向上向下滚动几次和 时停止工作。一些Rectangle s 不见了。

即使使用单个 DataTrigger 也会重现此问题, 但它确实 不是 重构时ListBox.Height超过 178 .

示例 GIF - 缺少绿线!:

Regular scroll works, but fast scroll cause it binding to 'loose-it'

MainWindow.Xaml 源代码:

<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();
}
}
}

MyModel.cs 来源:
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"
};
}
}
}

最佳答案

由于PreviousData绑定(bind)与虚拟化不可靠,您可以通过设置 VirtualizingPanel.IsVirtualizing="False" 禁用虚拟化在 ListBox ,或者让您的绑定(bind)虚拟化准备就绪。

处理此类问题的一种方法是创建自定义列表框(在我的示例代码中为 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>

关于wpf - 绑定(bind) {RelativeSource PreviousData} 在特定情况下会中断绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44005571/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com