У меня есть решение для вас с небольшой ошибкой. Чтобы переключить PanningMode
, вам необходимо нажать «Вверх». Возможно, вы можете найти ошибку, которая работает без «Touch Up» еще раз.
После изменения PanningMode
родительского ScrollViewer
события Touch
больше не были перенаправлены внутреннему ребенку ScrollViewer
. Поэтому я также попытался перенаправить события касания на родителя ScrollViewer
. Возможно, у меня есть только ошибка в моей логике.
public class BubbleTouch : Behavior
{
public ScrollViewer ParentElement
{
get => (ScrollViewer) GetValue(ParentElementProperty);
set => SetValue(ParentElementProperty, value);
}
///
/// The DependencyProperty.
///
public static readonly DependencyProperty ParentElementProperty = DependencyProperty.Register("ParentElement", typeof(ScrollViewer), typeof(BubbleTouch), new PropertyMetadata(null));
private Brush _DefaultBrush;
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.TouchMove += _ChildMove;
AssociatedObject.TouchDown += _ChildDown;
AssociatedObject.TouchUp += _ChildUp;
ParentElement.TouchMove += _ParentMove;
ParentElement.TouchDown += _ParentDown;
ParentElement.TouchUp += _ParentUp;
}
protected override void OnDetaching()
{
AssociatedObject.TouchMove -= _ChildMove;
AssociatedObject.TouchDown -= _ChildDown;
AssociatedObject.TouchUp -= _ChildUp;
base.OnDetaching();
}
private TouchPoint _ParentStartPosition;
private bool _ParentTouchDown;
private bool _ParentMoving;
private void _ParentDown(object sender, TouchEventArgs e)
{
_ParentTouchDown = true;
_ParentStartPosition = e.GetTouchPoint(Application.Current.MainWindow);
}
private void _ParentMove(object sender, TouchEventArgs e)
{
if (_ParentTouchDown && !_ParentMoving)
{
double deltaX = _ParentStartPosition.Bounds.X - e.GetTouchPoint(Application.Current.MainWindow).Bounds.X;
double deltaY = _ParentStartPosition.Bounds.Y - e.GetTouchPoint(Application.Current.MainWindow).Bounds.Y;
Trace.WriteLine($"{deltaX} | {deltaY}");
if (deltaX > deltaY && deltaX > 5)
{
AssociatedObject.PanningMode = PanningMode.None;
AssociatedObject.Background = Brushes.Aqua;
ParentElement.PanningMode = PanningMode.HorizontalOnly;
_ParentMoving = true;
}
else if (deltaY > deltaX && deltaY > 5)
{
AssociatedObject.PanningMode = PanningMode.VerticalOnly;
AssociatedObject.Background = Brushes.ForestGreen;
ParentElement.PanningMode = PanningMode.HorizontalOnly;
_ParentMoving = true;
}
}
}
private void _ParentUp(object sender, TouchEventArgs e)
{
_ParentTouchDown = false;
_ParentMoving = false;
AssociatedObject.Background = _DefaultBrush;
}
private TouchPoint _ChildStartPosition;
private bool _ChildTouchDown;
private bool _ChildMoving;
private void _ChildDown(object sender, TouchEventArgs e)
{
_DefaultBrush = AssociatedObject.Background;
_ChildTouchDown = true;
_ChildStartPosition = e.GetTouchPoint(Application.Current.MainWindow);
}
private void _ChildMove(object sender, TouchEventArgs e)
{
if (_ChildTouchDown && !_ChildMoving)
{
double deltaX = _ChildStartPosition.Bounds.X - e.GetTouchPoint(Application.Current.MainWindow).Bounds.X;
double deltaY = _ChildStartPosition.Bounds.Y - e.GetTouchPoint(Application.Current.MainWindow).Bounds.Y;
Trace.WriteLine($"{deltaX} | {deltaY}");
if (deltaX > deltaY && deltaX > 5)
{
AssociatedObject.PanningMode = PanningMode.None;
AssociatedObject.Background = Brushes.Aqua;
ParentElement.PanningMode = PanningMode.HorizontalOnly;
_ChildMoving = true;
}
else if (deltaY > deltaX && deltaY > 5)
{
AssociatedObject.PanningMode = PanningMode.VerticalOnly;
AssociatedObject.Background = Brushes.ForestGreen;
ParentElement.PanningMode = PanningMode.HorizontalOnly;
_ChildMoving = true;
}
}
if (AssociatedObject.PanningMode == PanningMode.None)
{
e.Handled = true;
}
}
private void _ChildUp(object sender, TouchEventArgs e)
{
AssociatedObject.Background = _DefaultBrush;
_ChildTouchDown = false;
_ChildMoving = false;
}
}
Вы можете использовать обратную косую черту, чтобы разбить команды на несколько строк.
for f in dev/scss/*.scss; do cat "$f"; echo; echo; done \
| additional-processing
После некоторых операторов, таких как &&
, ||
и |
, обратная косая черта не требуется. Баш знает, что команда не закончена. Если вы поместите |
в предыдущую строку, вам не понадобится обратный слеш.
for f in dev/scss/*.scss; do cat "$f"; echo; echo; done |
additional-processing
Таким образом, вы можете объединить большое количество команд.
for f in dev/scss/*.scss; do cat "$f"; echo; echo; done |
foo |
bar |
baz
Если цикл становится громоздким, вам также следует рассмотреть его оборачивание в вызов функции. Мне нравится такой подход, потому что это означает, что вам не нужно втискивать все в небольшое количество строк. Вы можете дать петле больше передышки с каждой командой на отдельной строке.
loop() {
for f in dev/scss/*.scss; do
cat "$f"
echo
echo
done
}
Это позволяет сократить ваш конвейер до чего-то более читабельного, например:
loop | foo | bar | baz
P.S. Всегда заключайте в кавычки расширения переменных. Напишите cat "$f"
, чтобы имена файлов с пробелами и другими специальными символами обрабатывались правильно. Sup>
Самый прямой ответ таков:
IFS='\0'
result=`for f in dev/scss/*.scss; do cat $f; done`
echo $result
IFS
предназначен для того, чтобы избежать путаницы с вашими пробелами и окончаниями строк, интерпретируя их как границы элементов. (Без этого вы в конечном итоге получите echo $result
, который выводит все бесполезно в одну строку.)
Но подстановочный знак расширяется на месте, и в зависимости от того, сколько файлов соответствует глобу, вы можете получить слишком длинная для обработки команда Вам почти наверняка лучше использовать find
, но это также зависит от того, для чего вы хотите содержимое этих файлов. Может быть более простой способ сделать то, что вы пытаетесь выполнить, не сохраняя сначала содержимое всех файлов в промежуточной переменной.