Анимация и GridLength в формах Xamarin
У меня есть модель класса
public class Model : INotifyPropertyChanged
...
private GridLength detailsPanelHeight { get; set; }
public GridLength DetailsPanelHeight
{
get { return detailsPanelHeight; }
set
{
if (!GridLength.Equals(detailsPanelHeight, value))
{
detailsPanelHeight = value;
OnPropertyChanged("DetailsPanelHeight");
}
}
}
...
часть кода XAML:
<RowDefinition Height="{Binding DetailsPanelHeight}" />
код для анимации (плавное изменение высоты строки):
var animate = new Animation(d => currentItem.DetailsPanelHeight = d, 0, 100);
animate.Commit(this, "ExpandAnimation", 50, 1000, Easing.SpringOut);
код, чтобы свернуть строку:var animate = new Animation(d => currentItem.DetailsPanelHeight = d, 100, 0);
animate.Commit(this, "CollapseAnimation", 50, 1000, Easing.SpringOut);
Это работает в первый раз, но во второй раз я получаю сообщение об ошибке: "значение меньше 0 или не является числом \n Параметр имя: значение". я вижу d
значение меньше нуля.
Что я могу сделать, чтобы решить эту проблему?
1 ответ
Я использовал что-то подобное, что отлично сработало для меня. Я надеюсь, что это подходит и для вас.
Эта анимация сворачивает ячейку представления при вызове команды после вызова действия удаления. Вот код:
Обработчик события касания:
private async void RemoveButtonTapped(object sender, EventArgs e)
{
Parallel.Invoke(() =>
{
if (RemoveCommand?.CanExecute(RemoveCommandParameter) ?? false)
RemoveCommand.Execute(RemoveCommandParameter);
},
AnimatedDestruction);
}
Анимационный метод
private async void AnimatedDestruction()
{
uint transitionTime = 300;
decimal delayFactor = 1.2m;
// Note: stackPanel is the viewCell's top-level container
await Task.WhenAll(
stackPanel.FadeTo(0, Convert.ToUInt32(transitionTime * delayFactor), Easing.CubicInOut),
View.InterpolateValue(stackPanel.Height, 0, Transition, transitionTime, Easing.CubicInOut)
);
}
Функция обратного вызова перехода
private void Transition(double value)
{
const double minHeightValue = 0.001;
value = value <= minHeightValue ? minHeightValue : value;
Height = value;
ForceUpdateSize();
}
InterpolateValue
функция как метод расширения (очень многоразовый)
public static Task<bool> InterpolateValue(this View view, double initialValue, double endValue, Action<double> transformIteration, uint length, Easing easing)
{
Task<bool> ret = new Task<bool>(() => false);
if (!view.AnimationIsRunning(nameof(InterpolateValue)))
{
try
{
easing = easing ?? Easing.Linear;
var taskCompletionSource = new TaskCompletionSource<bool>();
view.Animate(nameof(InterpolateValue), ((_double) => initialValue - (initialValue * _double)), transformIteration, 16, length, easing, (v, c) => taskCompletionSource.SetResult(c));
ret = taskCompletionSource.Task;
}
catch
{
// supress animation overlapping errors
}
}
return ret;
}
Я надеюсь, что это работает для вас.