强制枢轴项目在显示之前预加载 [英] Force pivot item to preload before it's shown
问题描述
我有一个包含多个 PivotItem 的 Pivot,其中一个包含一个画布,可将其项目放置在动态位置(取决于数据).我得到了数据,我可以在用户选择这个项目之前将这些项目放在它们的位置(这不是第一个枢轴).但是,只有当我选择 PivotItem 时,画布才会自行呈现,因此您可以看到它在按原样显示之前闪烁.
I have a Pivot with several PivotItems, one of which contains a canvas that places its items in dynamic locations (depending on the data). I get the data, and I can place the items in their place before the user can choose this item (this isn't the first pivot). However, only when I select the PivotItem, the canvas renders itself, so you can see it flicker before it's shown as it should.
有没有办法强制画布在显示之前渲染,以便在用户看到它时一切准备就绪?
Is there a way to force the canvas to render before it's shown, so everything's prepared by the time the user sees it?
我的代码如下所示:
在 page.xaml.cs 中:
In the page.xaml.cs:
private async void GameCenterView_OnDataContextChanged(object sender, EventArgs e)
{
// Load data...
// Handle other pivots
// This is the problem pivot
if (ViewModel.CurrentGame.SportTypeId == 1)
{
_hasLineups = ViewModel.CurrentGame.HasLineups.GetValueOrDefault();
HasFieldPositions = ViewModel.CurrentGame.HasFieldPositions.GetValueOrDefault();
// I only add the pivot when I need it, otherwise, it won't be shown
if (_hasLineups)
{
if (MainPivot.Items != null) MainPivot.Items.Add(LineupPivotItem);
}
if (HasFieldPositions)
{
// Here I place all the items in their proper place on the canvas
ArrangeLineup(ViewModel.TeamOneLineup, TeamOneCanvas);
ArrangeLineup(ViewModel.TeamTwoLineup, TeamTwoCanvas);
}
}
// Handle other pivots
}
private void ArrangeLineup(ObservableCollection<PlayerInLineupViewModel> teamLineup, RationalCanvas canvas)
{
if (teamLineup == null)
return;
foreach (var player in teamLineup)
{
var control = new ContentControl
{
Content = player,
ContentTemplate = LinupPlayerInFieldDataTemplate
};
control.SetValue(RationalCanvas.RationalTopProperty, player.Player.FieldPositionLine);
control.SetValue(RationalCanvas.RationalLeftProperty, player.Player.FieldPositionSide);
canvas.Children.Add(control);
}
}
画布不是库存画布.我创建了一个新画布,根据它们的相对位置显示项目(我以 0-99 的比例获得位置).
The canvas isn't the stock canvas. I created a new canvas that displays items according to their relative position (I get the positions in a scale of 0-99).
逻辑发生在 OverrideArrange 方法中:
The logic happens in the OverrideArrange method:
protected override Size ArrangeOverride(Size finalSize)
{
if (finalSize.Height == 0 || finalSize.Width == 0)
{
return base.ArrangeOverride(finalSize);
}
var yRatio = finalSize.Height/100.0;
var xRatio = finalSize.Width/100.0;
foreach (var child in Children)
{
var top = (double) child.GetValue(TopProperty);
var left = (double) child.GetValue(LeftProperty);
if (top > 0 || left > 0)
continue;
var rationalTop = (int) child.GetValue(RationalTopProperty);
var rationalLeft = (int) child.GetValue(RationalLeftProperty);
if (InvertY)
rationalTop = 100 - rationalTop;
if (InvertX)
rationalLeft = 100 - rationalLeft;
child.SetValue(TopProperty, rationalTop*yRatio);
child.SetValue(LeftProperty, rationalLeft*xRatio);
}
return base.ArrangeOverride(finalSize);
}
谢谢.
推荐答案
您可以尝试多种技巧.例如:
There are several tricks you could try. For example:
- 在您的
ArrangeOverride
中,如果自上次执行以来大小没有改变(并且数据相同),您可以短路逻辑 - 确保您正在收听
Pivot
上告诉您准备演示的事件 - 例如PivotItemLoading
- 您可以让控件实际上不是
Pivot
的一部分,而是位于父容器中(例如Grid
)并使用Opacity
为零.然后在目标PivotItem
出现时将其设置为 100.
- In your
ArrangeOverride
you can short-circuit the logic if the size hasn't changed since last time you executed (and the data is the same) - Make sure you're listening to the events on
Pivot
that tell you to get ready for presentation -PivotItemLoading
for example - You can have the control not actually be part of the
Pivot
, but instead be in the parent container (eg aGrid
) and have it withOpacity
of zero. Then set it to 100 when the targetPivotItem
comes into view.
这篇关于强制枢轴项目在显示之前预加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!