Nano Hash - криптовалюты, майнинг, программирование

Отрисовка холста UWP за пределами допустимого диапазона

У меня есть холст (не InkCanvas!), И я могу рисовать на нем полилинии. Это работает нормально, но есть огромная проблема с выводом за границы, как показано в GIF ниже.

Правая сторона - холст, левая сторона - пустое место.

Мой холст находится внутри ScrollViewer, а ScrollViewer - внутри GridView.

Я попытался поймать указатель, покидающий холст, с помощью следующих обработчиков событий:

canvas.PointerExited += Canvas_PointerExited;
canvas.PointerCaptureLost += Canvas_PointerCaptureLost;

Но похоже, что эти события запускаются слишком медленно.

Я попытался использовать свойство Clip своего холста, но поведение не изменилось. И для холста UWP нет свойства ClipToBound.

Все мое представление создается в Code-Behind, потому что мне нужно создать несколько холстов в одном представлении.

Есть ли способ остановить такое поведение?

РЕДАКТИРОВАТЬ1:

По запросу: больше понимания моего кода.

Страница XAML выглядит так:

<Grid x:Name="BoundingGrid">
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="15*"/>
    </Grid.RowDefinitions>
    <Grid x:Name="InkGrid" VerticalAlignment="Top" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" />
    <Grid x:Name="CanvasGrid" Grid.Row="1" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" VerticalAlignment="Top"/>
</Grid>

Все это внутри страницы.

Мой код выглядит так:

Мои конструкторы:

public ImprovedCanvasManager(Grid boundingGrid, Grid overviewGrid, string filepath, double height)
    {
        drawCanvas = new Canvas();

        overviewGrid.Loaded += OverviewGrid_Loaded;
        overviewGrid.SizeChanged += OverviewGrid_SizeChanged;

        RowDefinition rd = new RowDefinition();
        rd.Height = new GridLength(height);

        overviewGrid.RowDefinitions.Add(rd);

        InitializeScrollViewer();

        Grid.SetRow(scroll, overviewGrid.RowDefinitions.Count);
        Grid.SetColumn(scroll, 0);

        scroll.Content = drawCanvas;
        overviewGrid.Children.Add(scroll);
        LoadImage(filepath);
    }

        public ImprovedCanvasManager(Grid boundingGrid, Grid overviewGrid, Grid inkToolGrid, string filepath, double height = 1000) : this(boundingGrid, overviewGrid, filepath, height)
    {
        AddDrawingToolsToCanvas(inkToolGrid, overviewGrid);
        EnableDrawingOnCanvas(drawCanvas);
    }

У меня есть только два конструктора, чтобы упростить мне создание холстов с возможностью рисования и без способности рисовать.

Вот как я инициализирую свой ScrollViewer:

private void InitializeScrollViewer()
    {
        scroll = new ScrollViewer();

        scroll.VerticalAlignment = VerticalAlignment.Top;
        scroll.VerticalScrollMode = ScrollMode.Auto;
        scroll.HorizontalScrollMode = ScrollMode.Auto;
        scroll.VerticalScrollBarVisibility = ScrollBarVisibility.Visible;
        scroll.HorizontalScrollBarVisibility = ScrollBarVisibility.Visible;
        scroll.ZoomMode = ZoomMode.Enabled;
        scroll.ManipulationMode = ManipulationModes.All;

        scroll.MinZoomFactor = 1;
        scroll.MaxZoomFactor = 3;
    }

Это единственные строки кода, которые влияют на построение любого представления.

Изменить 2:

Мой холст не заполняет окружающую сетку слева, а внизу.

введите описание изображения здесь

06.10.2017

  • Один быстрый ответ на вышеизложенное: определения строк со звездочками предназначены для процентов. Итак, 15* на самом деле равно 1500%. Когда вы используете звездочки, я настоятельно рекомендую, чтобы все значения равнялись единице. <RowDefinition Height=".85*"/> и <RowDefinition Height=".15*" /> 07.10.2017
  • Где добавлена ​​ломаная линия? Как это собирается? 07.10.2017
  • Благодарю за этот ответ. И я обнаружил, что ваш код работает отлично. Но мой холст недостаточно широкий, чтобы заполнить окружающую сетку. Таким образом, ваш код идеально обрезает линию по верхнему и нижнему краю, но не по левой и правой стороне. Выкладываю скриншот в своем квестоне. 07.10.2017
  • Хорошо, похоже, вам следует использовать изображение, а не холст. В моем ответе замените canvas ссылкой на изображение. Вы можете видеть небольшое отступление в левой части изображения. Похоже на мертвое пространство холста. 07.10.2017
  • Проблема в этом сценарии заключается в том, что изображение является фоном моего холста. Но теперь я знаю, что мои полилинии построены правильно, и что проблема заключалась в моем непонимании того, как работают родительские элементы моего холста. 07.10.2017
  • Если вы установите цвет фона на панелях холста / сетки, вы сможете лучше визуализировать вещи. Вы увидите границы. 07.10.2017

Ответы:


1

Код в вашем PointerMoved обработчике должен относиться к холсту.

private void OnPointerMoved(object sender, PointerRoutedEventArgs e)
{
    var point = e.GetCurrentPoint(canvas); // <-- relative to canvas.
    var x = point.Position.X;
    var y = point.Position.Y;

    x = Math.Max(x, 0);
    y = Math.Max(y, 0);
    x = Math.Min(canvas.ActualWidth, x);
    y = Math.Min(canvas.ActualHeight, y);


    // add point to polyline...
}

Если значения x / y отрицательны или превышают размер холста, они выходят за границы. Вы можете либо ограничить точку границей холста, как это делает код выше, либо полностью отказаться от точки.

07.10.2017
  • Теоретически ваш код работает отлично. Когда я очень медленно прорисовываю край холста, он идеально обрезает линию. Но если я рисую очень быстро, я все равно могу рисовать за пределами поля. Неужели эти события такие медленные? 07.10.2017
  • Этого не должно быть. Если вы ограничите значения x и y точки, они никогда не должны выводиться за пределы холста, независимо от скорости. Есть ли у вас какие-либо отступы / поля / преобразования, влияющие на рисунок? Может быть, опубликуйте еще немного кода о том, как вы рисуете линии, и я помогу вам отладить. 07.10.2017
  • Я добавил подробности к своему вопросу. Я надеюсь, что эта информация будет полезной. Возможно, важно сказать, что мой холст сначала получает свой размер после загрузки сетки, потому что я не нашел другого способа получить для него высоту и ширину до того, как окружающая сетка была построена на виде. 07.10.2017
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..