Похоже, что Canvas вашего окна содержит несколько ContentControls. Один из них представляет интерес и содержит сетку, которая, в свою очередь, содержит, во-первых, экземпляр вашего класса MoveLine, а во-вторых, ContentPresenter, содержащий Rectangle.
Итак, ваше визуальное дерево выглядит примерно так:
Window1
Canvas
...
ContentControl
Grid
MoveLine
ContentPresenter
Rectangle (mRect)
Вы пытаетесь обработать событие в MoveLine и изменить прямоугольник ContentPresenter, mRect. Вы можете ссылаться на mRect только в контексте Window1.
Проблема в том, что для WPF класс MoveLine может появиться где угодно, и поэтому, естественно, он понятия не имеет, что mRect может означать для любого конкретного экземпляра MoveLine. Как это происходит, мы знаем, что mRect является дочерним Rectangle родственного ContentPresenter, который разделяет родительский элемент с экземпляром MoveLine.
Если вы абсолютно уверены, что MoveLine будет использоваться только здесь, вы можете использовать методы Get.Parent (), GetChildrenCount () и GetChild () System.Windows.Media.VisualTreeHelper. Вам нужно пройти «вверх» на один уровень от MoveLine, через один, а затем вниз на один. Вы также можете перейти на один уровень вверх, а затем искать потомков с именем «mName». См. Как найти элементы управления WPF по имени или типу? . Это не очень вменяемый подход.
Я бы больше соблазнил поместить код обработки на холст или, по крайней мере, в его ContentControls, поскольку на них влияют. Я бы добавил RoutedEvent с именем, скажем, ThumbMoved, в MoveLine. RoutedEvents могут "пузыриться", чтобы быть обработанными наследственными средствами управления. Затем вы можете добавить обработчик для этого события в ContentControl, содержащий ваш Rectangle, и it может затем использовать mName для настройки прямоугольника. См. Как: создать пользовательское перенаправленное событие и Как: обработать перенаправленное событие . Очень грубо:
class MoveLine : Thumb
{
public static readonly RoutedEvent ThumbMovedEvent =
EventManager.RegisterRoutedEvent("ThumbMoved",
RoutingStrategy.Bubble,
typeof(DragDeltaRoutedEventHandler),
typeof(MoveLine));
public event DragDeltaRoutedEventHandler ThumbMoved
{
add { AddHandler(ThumbMovedEvent, value); }
remove { RemoveHandler(ThumbMovedEvent, value); }
}
void RaiseThumbMoved(DragDeltaEventArgs e)
{
DragDeltaRoutedEventArgs newEventArgs =
new DragDeltaRoutedEventArgs(ThumbMovedEvent, e);
RaiseEvent(newEventArgs);
}
private void MoveThumb_DragDelta(object sender, DragDeltaEventArgs e)
{
RaiseThumbMoved(e);
...
}
(где DragDeltaRoutedEventArgs - это класс, производный от RoutedEventArgs, который предоставляет те же дельты, что и DragDeltaEventArgs.) А затем в XAML вашего окна:
...
<ContentControl Width="5" Height="400" Canvas.Top="80" Canvas.Left="350"
Template="{StaticResource DesignerItemTemplateLine}"
MoveLine.ThumbMoved="MoveLine_ThumbMoved">
<Rectangle Fill="Blue" IsHitTestVisible="False" Name="mRect">
...
И код позади:
namespace DiagramDesigner
{
public partial class Window1 : Window
{
private void MoveLine_ThumbMoved(object sender, DragDeltaRoutedEventArgs e)
{
mRect.Foo = "Bar"; // mRect is recognised by Window1.
}
...