Xaml名称范围

时间:2011-03-29 13:00:06

标签: wpf xaml scope

我需要从C#(他的RotateTransform角度)

更改Rectangle属性

问题是在XAML中声明了矩形,并且在C#代码超出了矩形的范围,我尝试使用Name,而X:Name没有成功,

我该怎么做?

-------------编辑--------------------

    <ContentControl Width="5" Height="400" Canvas.Top="80" Canvas.Left="350"               
                Template="{StaticResource DesignerItemTemplateLine}">
        <Rectangle Fill="Blue" IsHitTestVisible="False" Name="mRect">
          <Rectangle.RenderTransform>
            <TransformGroup>          
                <RotateTransform Angle="45"/>
            </TransformGroup>
          </Rectangle.RenderTransform>          
        </Rectangle>
    </ContentControl>

C#代码

 private void MoveThumb_DragDelta(object sender, DragDeltaEventArgs e)
    {
        Control designerItem = this.DataContext as Control;

        if (designerItem != null)
        {
            double left = Canvas.GetLeft(designerItem);
            double top = Canvas.GetTop(designerItem);

            if (mRect != null)// This line don't compile
            Canvas.SetLeft(designerItem, left + e.HorizontalChange);
            Canvas.SetTop(designerItem, top + e.HorizontalChange);
            //Canvas.SetTop(designerItem, top + e.VerticalChange);
        }
    }

你可以注意到“if(mRect!= null)”通过编译

------------- Seconde编辑---所有代码-------------------------- -

<Window x:Class="DiagramDesigner.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:s="clr-namespace:DiagramDesigner"
    WindowStartupLocation="CenterScreen"
    Title="Move"
    Height="550" Width="750">

<!-- MoveThumb Template -->
<ControlTemplate x:Key="MoveThumbTemplate" TargetType="{x:Type s:MoveThumbUpDwon}">
  <Rectangle Fill="Transparent"/>
</ControlTemplate>

<!-- MoveThumb Template -->
<ControlTemplate x:Key="MoveThumbTemplateLeftRight" TargetType="{x:Type s:MoveThumbLeftRight}">
      <Rectangle Fill="Transparent"/>
</ControlTemplate>
 <!-- MoveThumb Template -->
 <ControlTemplate x:Key="MoveLineTemplate" TargetType="{x:Type s:MoveLine}">
        <Rectangle Fill="Black">
            <Rectangle.RenderTransform>
                <TransformGroup>

                    <RotateTransform Angle="45"/>
                </TransformGroup>
            </Rectangle.RenderTransform>
        </Rectangle>
    </ControlTemplate>

    <!-- Designer Item Template-->
<ControlTemplate x:Key="DesignerItemTemplate" TargetType="ContentControl">
  <Grid DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}">
    <s:MoveThumbUpDwon Template="{StaticResource MoveThumbTemplate}" Cursor="SizeAll"/>

    <ContentPresenter Content="{TemplateBinding ContentControl.Content}"/>
  </Grid>
</ControlTemplate>

<ControlTemplate x:Key="DesignerItemTemplateLeftRight" TargetType="ContentControl">
    <Grid DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}">
        <s:MoveThumbLeftRight Template="{StaticResource MoveThumbTemplateLeftRight}" Cursor="SizeAll"/>

        <ContentPresenter Content="{TemplateBinding ContentControl.Content}"/>
    </Grid>
</ControlTemplate>

<ControlTemplate x:Key="DesignerItemTemplateLine" TargetType="ContentControl">
    <Grid DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}">
        <s:MoveLine Template="{StaticResource MoveLineTemplate}" Cursor="SizeAll"/>

        <ContentPresenter Content="{TemplateBinding ContentControl.Content}"/>
    </Grid>
</ControlTemplate>
</Window.Resources>

 <Canvas>
    <ContentControl Width="600"

                Height="5"

                Canvas.Top="250"
                Canvas.Left="80"

                Template="{StaticResource DesignerItemTemplate}">
  <Rectangle Fill="Blue"
           IsHitTestVisible="False"/>
</ContentControl>

    <ContentControl Width="5"

                Height="400"

                Canvas.Top="80"
                Canvas.Left="350"


                Template="{StaticResource DesignerItemTemplateLeftRight}">
        <Rectangle Fill="Blue"

           IsHitTestVisible="False"/>
    </ContentControl>

    <ContentControl Width="5" Height="400" Canvas.Top="80" Canvas.Left="350"               
                Template="{StaticResource DesignerItemTemplateLine}">
        <Rectangle Fill="Blue" IsHitTestVisible="False" Name="mRect">
          <Rectangle.RenderTransform>
            <TransformGroup>          
                <RotateTransform Angle="45"/>
            </TransformGroup>
          </Rectangle.RenderTransform>          
        </Rectangle>
    </ContentControl>


</Canvas>

现在是C#代码

using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Shapes;
using System.Windows.Media;
using System.Windows;

namespace DiagramDesigner
{
    public class MoveThumbUpDwon : Thumb
    {
        public MoveThumbUpDwon()
        {
            DragDelta += new DragDeltaEventHandler(this.MoveThumb_DragDelta);
        }

    private void MoveThumb_DragDelta(object sender, DragDeltaEventArgs e)
    {
        Control designerItem = this.DataContext as Control;

        if (designerItem != null)
        {
            double left = Canvas.GetLeft(designerItem);
            double top = Canvas.GetTop(designerItem);

            //Canvas.SetLeft(designerItem, left + e.HorizontalChange);
            Canvas.SetTop(designerItem, top + e.VerticalChange);
        }
    }
}

public class MoveThumbLeftRight : Thumb
{
    public MoveThumbLeftRight()
    {
        DragDelta += new DragDeltaEventHandler(this.MoveThumb_DragDelta);
    }

    private void MoveThumb_DragDelta(object sender, DragDeltaEventArgs e)
    {
        Control designerItem = this.DataContext as Control;

        if (designerItem != null)
        {
            double left = Canvas.GetLeft(designerItem);
            double top = Canvas.GetTop(designerItem);

            Canvas.SetLeft(designerItem, left + e.HorizontalChange);
            //Canvas.SetTop(designerItem, top + e.VerticalChange);
        }
    }
}

public class MoveLine : Thumb
{
    public MoveLine()
    {
        DragDelta += new DragDeltaEventHandler(this.MoveThumb_DragDelta);
    }

    private void MoveThumb_DragDelta(object sender, DragDeltaEventArgs e)
    {
        Control designerItem = this.DataContext as Control;

        if (designerItem != null)
        {
            double left = Canvas.GetLeft(designerItem);
            double top = Canvas.GetTop(designerItem);
         //   if (mRect != null)

            Canvas.SetLeft(designerItem, left + e.HorizontalChange);
            Canvas.SetTop(designerItem, top + e.HorizontalChange);
            //Canvas.SetTop(designerItem, top + e.VerticalChange);
        }
    }
}

}

2 个答案:

答案 0 :(得分:0)

引用在代码隐藏中,但它似乎与xaml不同:

<Window x:Class="DiagramDesigner.Window1"> vs public class MoveLine : Thumb

如果要从代码隐藏中引用xaml定义的元素,它们必须是同一个类。

答案 1 :(得分:0)

看起来你的窗口的Canvas包含许多ContentControls。其中一个是有意义的,并且包含一个网格,该网格首先包含MoveLine类的实例,其次包含一个包含Rectangle的ContentPresenter。

所以你的视觉树看起来大致如下:

 Window1
   Canvas
     ...
     ContentControl
       Grid
         MoveLine
         ContentPresenter
           Rectangle (mRect)

您正在尝试处理MoveLine中的事件并修改ContentPresenter的Rectangle,mRect。您只能在Window1的上下文中引用mRect。

问题在于,就WPF而言,MoveLine类可以出现在任何地方,因此很自然地,它不知道mRect对任何特定的MoveLine实例意味着什么。碰巧我们知道mRect是兄弟ContentPresenter的子Rectangle,它与MoveLine的实例共享一个父。

如果您完全确定只会在此处使用MoveLine,则可以使用System.Windows.Media.VisualTreeHelper的GetParent(),GetChildrenCount()和GetChild()方法。您需要从MoveLine“向上”一个级别,跨越一个级别,然后向下一个级别。您也可以上升一级,然后搜索名为“mName”的后代。见How can I find WPF controls by name or type?。这不是一个非常理智的方法。

我更倾向于将处理代码放到画布上,或者至少放入其ContentControls中,因为它们是受影响的。我会向MoveLine添加一个名为ThumbMoved的RoutedEvent。 RoutedEvents可以“冒泡”以由祖先控件处理。然后,您可以将此事件的处理程序添加到包含Rectangle的ContentControl,然后 it 可以使用mName调整矩形。请参阅How to: Create a Custom Routed EventHow to: Handle a Routed Event。非常粗略:

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.
        }
        ...