Реализуйте выбор в DrawingContext - PullRequest
0 голосов
/ 20 января 2011

У меня есть инфраструктурный код, который рисует прямоугольники с DrawingContext, и я хочу, чтобы у этих прямоугольников было событие click. как я могу это сделать?

вот так я рисую прямоугольник

dc.DrawRectangle (bg, Stroke, rect);

Ответы [ 3 ]

1 голос
/ 20 января 2011

Этот прямоугольник - просто пиксели, у него не может быть никаких событий.

Вам придется посмотреть на владельца (Контроль) этого DC. Или просто используйте элемент Rectangle.

0 голосов
/ 20 января 2011

Вы должны поместить ItemsControl и связать его свойство ItemsSource с коллекцией прямоугольников. Затем вы должны переопределить ItemsControl.ItemTemplate и предоставить свой собственный DataTemplate, который содержит пользовательский элемент управления, отображающий Rectangle. Этот пользовательский элемент управления способен обрабатывать события мыши.

XAML окна хоста:

<Window x:Class="Test.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:self ="clr-namespace:Test"
    Title="MainWindow" 
    Height="350" Width="700">
<Window.Resources>
    <DataTemplate x:Key="RectTemplate">
        <self:RectangleView />
    </DataTemplate>
</Window.Resources>
<Grid>
    <ItemsControl ItemsSource="{Binding Rectangles}" 
                  ItemTemplate="{StaticResource RectTemplate}">
    </ItemsControl>
</Grid>

и RectangleView:

<UserControl x:Class="Test.RectangleView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" >

Код позади MainWindow

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;
    }

    public IEnumerable<Rect> Rectangles
    {
        get 
        {
            yield return new Rect(new Point(10, 10), new Size(100, 100));
            yield return new Rect(new Point(50, 50), new Size(400, 100));
            yield return new Rect(new Point(660, 10), new Size(10, 100));
        }
    }
}

И код позади RectangleView:

public partial class RectangleView : UserControl
{
    public RectangleView()
    {
        InitializeComponent();
    }

    protected override void OnRender(DrawingContext drawingContext)
    {
        base.OnRender(drawingContext);
        drawingContext.DrawRectangle(Brushes.Orchid, new Pen(Brushes.OliveDrab, 2.0), (Rect)this.DataContext);
    }

    protected override void OnMouseDown(MouseButtonEventArgs e)
    {
        // HERE YOU CAN PROCCESS MOUSE CLICK
        base.OnMouseDown(e);
    }
}

Я бы порекомендовал вам узнать больше о ItemsControl, ItemContainers, DataTemplates и Styles.

P.S. Из-за временных ограничений я объединил логику вида и модели в один класс как для MainView, так и для RectangleView. В хорошей реализации у вас должна быть модель представления для MainView (MainModel) и модель представления для RectangleView (RectangleViewData), кроме того, MainModel объявляет свойство типа IEnumerable. Поскольку RectangleViewData замечает изменения свойств, MainModel может управлять им.

0 голосов
/ 20 января 2011

Вы можете использовать HitTest функциональность VisualTreeHelper. Что-то вроде этого должно помочь вам (выполняйте этот код, когда вы щелкаете мышью там, где хотите проверить попадания):

HitTestResult result = VisualTreeHelper.HitTest(this, mouselocation);

if (result.VisualHit.GetType() == typeof(DrawingVisual))
{
  //do your magic here. result.VisualHit will contain the rectangle that got hit
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...