- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个绑定(bind)到 ObservableCollection 的 WPF ListBox。当我向其中添加项目时,我想要一些动画来“吸引注意力”到“新到货”。有许多使用 DataTemplate 触发器和 FrameworkElment.Loaded 事件执行此操作的示例。效果很好,看起来很酷。
但是,滚动列表时也会触发相同的动画。这是由于 ListBox 的虚拟化功能,它会根据需要“加载”新项目。
有没有一种方法可以构造一个 ListBox,使其仅在 ObservableCollection 发生变化时触发“已加载”动画,而在滚动时不触发?
附言禁用虚拟化不是一种选择
最佳答案
为了触发动画,我创建了附加的依赖属性 AddNewItem( bool 值):
public class MyDependencyClass : DependencyObject
{
public static readonly DependencyProperty AddNewItemProperty;
public static void SetAddNewItem(DependencyObject DepObject, bool value)
{
DepObject.SetValue(AddNewItemProperty, value);
}
public static bool GetAddNewItem(DependencyObject DepObject)
{
return (bool)DepObject.GetValue(AddNewItemProperty);
}
static MyDependencyClass()
{
PropertyMetadata MyPropertyMetadata = new PropertyMetadata(false);
AddNewItemProperty = DependencyProperty.RegisterAttached("AddNewItem",
typeof(bool),
typeof(MyDependencyClass),
MyPropertyMetadata);
}
}
然后创建我们的依赖属性的边框(警告添加新项目):
<Border x:Name="WarningBorder" Style="{StaticResource HideBorderStyle}" local:MyDependencyClass.AddNewItem="False" Height="33" Background="#44515B" BorderThickness="0" Margin="65,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Opacity="0">
<TextBlock x:Name="WarningText" FontFamily="./#Segoe UI" TextAlignment="Center" Margin="0,5,0,0" FontSize="18" Foreground="Gainsboro" Text="You add new item" />
</Border>
样式 HideBorderStyle 包含当属性 AddNewItem=True 时触发的 DataTrigger。 HideBorderStyle 列表:
<Style x:Key="HideBorderStyle" TargetType="{x:Type Border}">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=WarningBorder, Path=(local:MyDependencyClass.AddNewItem), Mode=OneWay}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Width" BeginTime="0:0:0" From="0.0" To="427.0" Duration="0:0:0.5" />
<DoubleAnimation Storyboard.TargetProperty="Opacity" BeginTime="0:0:0" From="0.0" To="1.0" Duration="0:0:1.0" />
<DoubleAnimation Storyboard.TargetProperty="Opacity" BeginTime="0:0:5" From="1.0" To="0.0" Duration="0:0:1.0" />
<DoubleAnimation Storyboard.TargetProperty="Width" BeginTime="0:0:5" From="427.0" To="0.0" Duration="0:0:1.0" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
假设我们有一个 SampleListBox 和 AddButton:
<Grid>
<ListBox x:Name="SampleListBox" Width="400" Height="200" BorderThickness="1" BorderBrush="Black" DisplayMemberPath="Name" Background="AliceBlue" Loaded="SampleListBox_Loaded" />
<Button Content="Add" Width="50" Height="30" VerticalAlignment="Bottom" Click="AddButton_Click" />
</Grid>
AddButton_Click 列表:
private void AddButton_Click(object sender, RoutedEventArgs e)
{
PersonListBox.Add(new Person()
{
Name = "NewItem",
});
SampleListBox.ItemsSource = PersonListBox;
}
在 SampleListBox_Loaded 中,我初始化 SampleListBox 的数据并分配一个处理程序 NotifyCollectionChangedEventHandler,它在集合更改时调用。 SampleListBox_Loaded 事件列表:
private void SampleListBox_Loaded(object sender, RoutedEventArgs e)
{
PersonListBox.Add(new Person()
{
Name = "Peter Orange",
Age = 32,
Sample = "Sample",
});
SampleListBox.ItemsSource = PersonListBox;
PersonListBox.CollectionChanged += new NotifyCollectionChangedEventHandler(PersonListBox_CollectionChanged);
}
在 PersonListBox_CollectionChanged 中,我为依赖属性 AddNewItem 设置值 True。 PersonListBox_CollectionChanged list :
private void PersonListBox_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
MyDependencyClass.SetAddNewItem(WarningBorder, true);
}
}
现在,当一个项目被添加到集合中时,动画就会被触发。如果添加另一个元素动画不会触发。所以她工作了,你需要为以后的显示动画折叠值:
private void ResetButton_Click(object sender, RoutedEventArgs e)
{
MyDependencyClass.SetAddNewItem(WarningBorder, false);
}
在这种情况下,您需要决定何时重置动画值。
编辑:
要为添加的项目设置动画,我已经基于我之前的示例。但是现在 DataTrigger 的样式将分配给 ListBoxItem:
<ListBox x:Name="SampleListBox" local:MyDependencyClass.AddNewItem="False" local:MyDependencyClass.InitCountOfList="0" Width="400" Height="200" BorderThickness="1" BorderBrush="Black" DisplayMemberPath="Name" Background="AliceBlue" Loaded="SampleListBox_Loaded">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=SampleListBox, Path=(local:MyDependencyClass.AddNewItem), Mode=OneWay}" Value="True" />
<Condition Binding="{Binding ElementName=SampleListBox, Converter={StaticResource BoolToInitItemsConverter}}" Value="True" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" BeginTime="0:0:0" From="0.0" To="1.0" Duration="0:0:1.0" />
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
为了正确工作,动画(尤其是在程序开始时)是根据另一个属性创建的 - InitCountOfList (Int):
public class MyDependencyClass : DependencyObject
{
public static readonly DependencyProperty AddNewItemProperty, InitCountOfListProperty;
#region AddNewItem
public static void SetAddNewItem(DependencyObject DepObject, bool value)
{
DepObject.SetValue(AddNewItemProperty, value);
}
public static bool GetAddNewItem(DependencyObject DepObject)
{
return (bool)DepObject.GetValue(AddNewItemProperty);
}
#endregion
#region InitCountOfList
public static void SetInitCountOfList(DependencyObject DepObject, int value)
{
DepObject.SetValue(InitCountOfListProperty, value);
}
public static int GetInitCountOfList(DependencyObject DepObject)
{
return (int)DepObject.GetValue(InitCountOfListProperty);
}
#endregion
#region Constructor of DependencyProperty
static MyDependencyClass()
{
PropertyMetadata BoolPropertyMetadata = new PropertyMetadata(false);
PropertyMetadata IntPropertyMetadata = new PropertyMetadata(0);
AddNewItemProperty = DependencyProperty.RegisterAttached("AddNewItem",
typeof(bool),
typeof(MyDependencyClass),
BoolPropertyMetadata);
InitCountOfListProperty = DependencyProperty.RegisterAttached("InitCountOfList",
typeof(int),
typeof(MyDependencyClass),
IntPropertyMetadata);
}
#endregion
}
数据在 Window_ContentRendered 事件中初始化:
private void Window_ContentRendered(object sender, EventArgs e)
{
PersonListBox.Add(new Person()
{
Name = "Peter Orange",
});
SampleListBox.ItemsSource = PersonListBox;
// Set the initial number of collection
MyDependencyClass.SetInitCountOfList(SampleListBox, SampleListBox.Items.Count);
}
处理程序 NotifyCollectionChangedEventHandler 在 SampleListBox_Loaded 事件中分配:
private void SampleListBox_Loaded(object sender, RoutedEventArgs e)
{
PersonListBox.CollectionChanged += new NotifyCollectionChangedEventHandler(PersonListBox_CollectionChanged);
}
Handler 和 AddButton_Click 保持不变:
private void PersonListBox_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
MyDependencyClass.SetAddNewItem(SampleListBox, true);
}
}
private void AddButton_Click(object sender, RoutedEventArgs e)
{
PersonListBox.Add(new Person()
{
Name = "NewItem",
});
}
Converter BoolToInitItemsConverter,如果在开始期间没有添加元素,则返回 true:
/// <summary>
/// Return true, if count of collection > initial
/// </summary>
public class BoolToInitItemsConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
ListBox MyListBox = value as ListBox;
int InitCountOfList = MyDependencyClass.GetInitCountOfList(MyListBox);
if (MyListBox.Items.Count > InitCountOfList)
{
// Added a new element
return true;
}
// First run and we do not want
// to run the animation
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return DependencyProperty.UnsetValue as object;
}
}
现在动画工作只针对添加的项目。
关于WPF DataBound ListBox 添加动画但不滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17010396/
如果附加了 'not-scroll' 类,我希望我的 body 不滚动,否则它应该正常工作。 我已经搜索这个问题两天了,但找不到任何适合我的解决方案。 我想要的是向 body 添加一个 class,并
我发现似乎是 iOS Safari 中的错误(我正在 iOS 8 上进行测试)。当绝对定位的 iFrame 漂浮在一段可滚动内容上方时,滚动 iFrame 也会滚动下面的内容。以下 HTML (ava
我有以下代码来显示一系列投资组合图片,这些图片以 SVG 格式存储在滚动 div 中: 在 Safari 中滚动使用两根手指或鼠标滚轮当光标位于 SVG 之一上时不起作用。 该页
我想用 javascript 做的是: 一旦你向下滚动页面,将#sidebar-box-fixed 的位置从 position: relative; 更改为定位:固定;。改回position:rela
我对 Elasticsearch 的滚动功能有点困惑。在 elasticsearch 中,每当用户在结果集上滚动时,是否可以每次调用搜索 API?来自文档 "search_type" => "scan
我试图做到这一点,以便当我向上或向下滚动页面时,它会运行不同的相应功能。我发现了一个类似的问题here但我已经尝试了他们的答案并且没有运气。 注意:此页面没有正常显示的滚动条。没有地方可以滚动。 bo
(C语言,GTK库) 在我的表单上,我有一个 GtkDrawingArea 小部件,我在上面使用 Cairo 绘制 GdkPixbufs(从文件加载)。我想要完成的是能够在窗口大小保持固定的情况下使用
最近我一直在尝试创建一个拉到(刷新,加载更多)swiftUI ScrollView !!,灵感来自 https://cocoapods.org/pods/SwiftPullToRefresh 我正在努
我正在开发一个应用程序,其中有两个带有可放置区域的列表和一个带有可拖动项目的侧面菜单。 当我滚动屏幕时,项目的位置困惑。 我试图在谷歌上寻找一些东西,最后得到了这个问题:jQuery draggabl
我在 UIWebView 中加载了一个 HTML 表单,而我的 UIWebView 恰好从 View 的中间开始并扩展。我必须锁定此 webView 不滚动并将其放在 ScrollView 之上以允许
如何在每个元素而不是整个元素上应用淡入淡出(与其高度相比)? HTML: CSS: * { padding: 0; margin: 0; box-sizing: border
我想使用带有垂直轴的 PageView 并使用鼠标滚动在页面之间移动,但是当我使用鼠标滚动时页面不滚动...仅页面单击并向上/向下滑动时滚动。 有什么办法吗? 我想保留属性 pageSnapping:
我制作这个程序是为了好玩,但我被卡住了,因为程序在屏幕外运行。如何在不完全更改代码的情况下实现滚动条。 public static void main(String args[]) throws IO
我想使用带有垂直轴的 PageView 并使用鼠标滚动在页面之间移动,但是当我使用鼠标滚动时页面不滚动...仅页面单击并向上/向下滑动时滚动。 有什么办法吗? 我想保留属性 pageSnapping:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
使用 jquery 技术从 css-tricks.com 获得滚动/跟随侧边栏,如果您不知道我在说什么,这里是代码: $(function() { var $sidebar = $
我是 jQuery Mobile 新手。我需要向我的应用程序添加 Facebook 滑动面板功能。 我经历了 sliding menu panel ,它工作正常,但我在菜单面板中的内容超出了窗口大小,
有没有办法在 js 或 jQuery 或任何其他工具中检测 ctrl + 滚动。我正在尝试执行一些动态布局代码,我需要检测不同分辨率下的屏幕宽度,我通过使用 setTimeout() 的计时器实现了这
我有一部分html代码:
我想控制 RichTextBox 滚动,但在控件中找不到任何方法来执行此操作。 这样做的原因是我希望当鼠标光标位于 RichTextBox 控件上时鼠标滚轮滚动有效(它没有事件焦点:鼠标滚轮事件由表单
我是一名优秀的程序员,十分优秀!