Как выбрать ребенка в сетке? - PullRequest
0 голосов
/ 10 декабря 2018

Может кто-нибудь, пожалуйста, помогите мне с моей проблемой.Я создаю программу, которая может нарисовать прямоугольник на изображении.Я использую WPF и MVVM Pattern.

Требование.Зритель может масштабировать и панорамировать изображение.Нарисуйте прямоугольник с изменением размера и переместите нарисованный прямоугольник.

Тогда я нашел этот ответ по ссылке ниже

Pan & Zoom Image

Я реализовал класс ZoomBorder из ответа.

Тогда, потому что мне также нужно нарисовать прямоугольник.Я изменил код и добавил свойство зависимости, которое возвращает Rect

        public Rect Rect
        {
            get { return (Rect)GetValue(RectProperty); }
            set { SetValue(RectProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Rect.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty RectProperty =
            DependencyProperty.Register("Rect", typeof(Rect), typeof(ZoomBorder),
                new FrameworkPropertyMetadata(new Rect(), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, null));

И вот как я его использую

<Viewer:ZoomBorder x:Name="img" Rect="{Binding Rect}" IsDraw="{Binding IsDraw}">

            <Grid>

                <Image Height="{Binding ActualHeight, ElementName=img, UpdateSourceTrigger=PropertyChanged}" Width="{Binding ActualWidth, ElementName=img, UpdateSourceTrigger=PropertyChanged}" Stretch="None" Source="img_05_l.jpg"/>
                <ItemsControl ItemsSource="{Binding RectItems}">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <Canvas  x:Name="canvas" Background="Transparent"  Height="{Binding ActualHeight, ElementName=img, UpdateSourceTrigger=PropertyChanged}" Width="{Binding ActualWidth, ElementName=img, UpdateSourceTrigger=PropertyChanged}" />
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ItemsControl.ItemContainerStyle>
                        <Style TargetType="{x:Type ContentPresenter}">
                            <Setter Property="Canvas.Left" Value="{Binding X, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
                            <Setter Property="Canvas.Top" Value="{Binding Y, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

                        </Style>
                    </ItemsControl.ItemContainerStyle>
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Rectangle Width="{Binding Width}"
                                       Height="{Binding Height}" 
                                       Fill="Transparent" 
                                       Stroke="Blue" 
                                       StrokeThickness="1"  />
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>

            </Grid>
        </Viewer:ZoomBorder>

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

Затем, после нескольких часов поиска, я нашел этот блог, который изменяет размеры и перемещает объекты на холсте

http://www.voidcn.com/article/p-krlsqrhc-uw.html

но моя проблемаЯ не могу выбрать нарисованный прямоугольник на холсте.

Вот код для выбора элемента управления на холсте

// Handler for element selection on the canvas providing resizing adorner
        void myCanvas_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            // Remove selection on clicking anywhere the window
            if (selected)
            {
                selected = false;
                if (selectedElement != null)
                {
                    // Remove the adorner from the selected element
                    aLayer.Remove(aLayer.GetAdorners(selectedElement)[0]);                    
                    selectedElement = null;
                }
            }

            // If any element except canvas is clicked, 
            // assign the selected element and add the adorner
            if (e.Source != myCanvas)
            {
                _isDown = true;
                _startPoint = e.GetPosition(myCanvas);

                selectedElement = e.Source as UIElement;

                _originalLeft = Canvas.GetLeft(selectedElement);
                _originalTop = Canvas.GetTop(selectedElement);

                aLayer = AdornerLayer.GetAdornerLayer(selectedElement);
                aLayer.Add(new ResizingAdorner(selectedElement));
                selected = true;
                e.Handled = true;
            }
        }

Но моя проблема заключается в том, как я могу выбрать нарисованныйпрямоугольник? Проблема в том, что выбран элемент управления Grid, а не Canvas - как я могу решить эту проблему?

Если я собираюсь удалить Grid.У меня будет ошибка "свойство Child установлено более одного раза".Мне нужен как холст, так и изображение.Я не могу найти решение, поэтому я решил спросить здесь.

1 Ответ

0 голосов
/ 10 декабря 2018

Способ, которым работает разметка, заключается в том, что вы представляете коллекцию моделей представления (или что бы то ни было) в виде RectItems для элемента управления.

Каждая из них имеет шаблон в виде прямоугольника.

Если выхотите удалить один, затем возьмите его viewmodel из RectItems.Предполагая, что это наблюдаемая коллекция, она уведомит об измененной коллекции, и прямоугольник будет удален.

Конкретный RectItem будет datacontext для selectedElement, когда вы выполните:

 selectedElement = e.Source as UIElement;

datacontext и приведите его к объекту RectItem.

Затем получите ссылку на модель представления, где находится RectItems.Может быть, это текстовый текст окна.Затем вы можете использовать .Remove () для RectItems, чтобы убрать его.

...