gpt4 book ai didi

wpf - 有没有办法延迟 WPF DataBinding(改进渲染)?

转载 作者:行者123 更新时间:2023-12-04 15:26:25 27 4
gpt4 key购买 nike

这是我的问题。

ListBox A 显示 Observable Collection 中的所有项目。

ListBox B 仅显示在 ListBox A 中选择的那些项目。

    <ListBox ItemsSource="{Binding MyView}" Name="ListBoxA">
<ListBox ItemsSource="{Binding Path=SelectedItems,
ElementName=ListBoxA}" Name="ListBoxB">

当 ListBox A 中的选择发生变化时,会运行 StoryBoard。生成的 UI 是基于用户选择的滑入和滑出 ListBox B 的酷而流畅的幻灯片。

问题是,我的 ListBox A 数据只绑定(bind)了 Name 属性,而 ListBox B 数据绑定(bind)了几十个,在某些情况下甚至是数百个属性。

问题仍然存在,因为 WPF 中的数据绑定(bind)在呈现时(特别是在动态时)会创建一个短暂的 50-500 毫秒 UI 延迟。用户界面卡住。

这是可以忍受的。但是我的 StoryBoard 似乎被这个 DataBinding 延迟阻塞了。结果,UI 有点“卡”到位,而我流畅的 StoryBoard 没有被看到。

我通过附加到 StoryBoard.Completed 事件解决了这个问题。 StoryBoard 完成后,我为 ListBox B 设置 ItemsSource。

但是,这只有 50% 好。用户看到 StoryBoard 执行,是的。但是 ListBox B 生成的 UI 在动画之后仍然“捕捉”到 View 中。

在我看来,正确的解决方案是以某种方式指示在 ListBox B 中呈现的控件等待或延迟实际的数据绑定(bind)。这将允许 UI 被渲染并参与 StoryBoard - 但数据稍后“填充”(希望也延迟由 DataBinding 引起的延迟)。

有没有人遇到过类似的问题?

这是准确演示问题的 XAML(因为 StackOverflow 限制了问题的大小,您需要添加额外的 TextBoxes 才能真正看到明显的延迟):
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>

<x:Array Type="{x:Type sys:String}" x:Key="MyData">
<sys:String>One</sys:String>
<sys:String>Two</sys:String>
<sys:String>Three</sys:String>
<sys:String>Four</sys:String>
<sys:String>Five</sys:String>
<sys:String>Six</sys:String>
</x:Array>

<Storyboard x:Key="MyGrowStoryboard">
<ParallelTimeline>
<DoubleAnimation To="1" DecelerationRatio="0.5"
Duration="00:00:00.500"
Storyboard.TargetName="MyTransform"
Storyboard.TargetProperty="ScaleX" />
<DoubleAnimation To="1" DecelerationRatio="0.5"
Duration="00:00:00.500"
Storyboard.TargetName="MyTransform"
Storyboard.TargetProperty="ScaleY" />
</ParallelTimeline>
</Storyboard>
<Storyboard x:Key="MyShrinkStoryboard">
<ParallelTimeline>
<DoubleAnimation To=".1" DecelerationRatio="0.5"
Duration="00:00:00.500"
Storyboard.TargetName="MyTransform"
Storyboard.TargetProperty="ScaleX" />
<DoubleAnimation To=".1" DecelerationRatio="0.5"
Duration="00:00:00.500"
Storyboard.TargetName="MyTransform"
Storyboard.TargetProperty="ScaleY" />
</ParallelTimeline>
</Storyboard>

</Page.Resources>
<StackPanel>
<ListBox ItemsSource="{Binding Source={StaticResource MyData}}"
Name="ListBoxA">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<DataTemplate.Triggers>

<!-- grow -->
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Value="True"
Binding="{Binding Path=IsSelected,
RelativeSource={RelativeSource
Mode=FindAncestor,
AncestorType={x:Type ListBoxItem}}}" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard
Storyboard="{StaticResource MyGrowStoryboard}" />
</MultiDataTrigger.EnterActions>
<MultiDataTrigger.ExitActions>
<BeginStoryboard
Storyboard="{StaticResource MyShrinkStoryboard}" />
</MultiDataTrigger.ExitActions>
</MultiDataTrigger>

<!-- shrink -->
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Value="False"
Binding="{Binding Path=IsSelected,
RelativeSource={RelativeSource
Mode=FindAncestor,
AncestorType={x:Type ListBoxItem}}}" />
<Condition Value="1"
Binding="{Binding Path=SelectedItems.Count,
RelativeSource={RelativeSource
Mode=FindAncestor,
AncestorType={x:Type ListBox}}}" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard
Storyboard="{StaticResource MyShrinkStoryboard}" />
</MultiDataTrigger.EnterActions>
<MultiDataTrigger.ExitActions>
<BeginStoryboard
Storyboard="{StaticResource MyGrowStoryboard}" />
</MultiDataTrigger.ExitActions>
</MultiDataTrigger>

</DataTemplate.Triggers>
<TextBlock Text="{Binding .}">
<TextBlock.LayoutTransform>
<ScaleTransform ScaleX="1" ScaleY="1"
x:Name="MyTransform"/>
</TextBlock.LayoutTransform>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

<ListBox ItemsSource="{Binding Path=SelectedItems,
ElementName=ListBoxA}" Name="ListBoxB">
<ListBox.ItemTemplate>
<DataTemplate>
<UniformGrid Columns="10">
<!-- repeat this part MANY times (like 3000) ! -->
<TextBox Text="{Binding .}" />
<TextBox Text="{Binding .}" />
<TextBox Text="{Binding .}" />
<TextBox Text="{Binding .}" />
<TextBox Text="{Binding .}" />
</UniformGrid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</Page>

看起来像这样:

enter image description here

谢谢!

最佳答案

我以前从未遇到过类似的问题,据我所知,没有内置的方法来延迟 WPF 中的数据绑定(bind)。

我用 ListboxB 内的 1000+ 文本框尝试了你的代码。 ListboxB 的渲染速度非常快,但如果您仍想减少 ListboxB 的渲染时间,您可以尝试将以下代码添加到 ListboxB。

VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling"

这将仅在 ListBoxB 内生成当前可见的控件,因此它将改进 ListBoxB 的呈现。

您可以在 VirtualizingStackPanel 上查看我的文章.

希望这个答案对您有所帮助。

关于wpf - 有没有办法延迟 WPF DataBinding(改进渲染)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6754233/

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