none
[WPF 用户控件库] 将 这个控件库dll 添加到另一个exe应用程序中,我要求我的控件库可以在exe中被拖动 RRS feed

  • 问题

  • 这是我要定义的空间样式,由Rectangle 和 Glyphs 构成:

    public void Paint(ref Grid myGrid, Point TopLeft, double RectangleHeight, double RectangeleWidth, int RectangleStrokeDirectFlow, string Text, SolidColorBrush TextColor)
            {
                Grid g_rect = new Grid();
                Canvas.SetTop(g_rect, TopLeft.Y);
                Canvas.SetLeft(g_rect, TopLeft.X);
                g_rect.Height = RectangleHeight;
                g_rect.Width = RectangeleWidth;
    
                Rectangle rec = new Rectangle();
                rec.Stroke = Brushes.Black; //  方框 边线 颜色
                rec.Fill = Brushes.Orange;  //  方框 底色
                rec.HorizontalAlignment = HorizontalAlignment.Center;
                rec.VerticalAlignment = VerticalAlignment.Center;
                rec.Height = RectangleHeight;    //  方框 的 高
                rec.Width = RectangeleWidth;    //  方框 的 宽
                rec.RadiusX = 10;   //  方框 圆角的 x 半径
                rec.RadiusY = 10;   //  方框 圆角的 y 半径
                rec.StrokeDashArray.Add(2); //  方框 的 虚线
                rec.StrokeDashArray.Add(1); //  方框 的 虚线
                rec.StrokeThickness = 3;    //  方框 边线 的 粗细
    
                //  设定位置(只能 通过 Canvas 来 设置 方框 的 位置)
                Canvas.SetTop(rec, TopLeft.Y);     //  方框 在 Canvas 中的 位置    
                Canvas.SetLeft(rec, TopLeft.X);    //  方框 在 Canvas 中的 位置
    
                //  开始 方框 边线 虚线流动 动画
                if (RectangleStrokeDirectFlow != 0)
                {   //  RectangleStrokeDirectFlow != 0:就 显示 流动 动画
                    DoubleAnimation animation = new DoubleAnimation(3, 0, TimeSpan.FromSeconds(0.5));   //顺时针转动
                    if (RectangleStrokeDirectFlow < 0)  //  逆时针转动
                        animation = new DoubleAnimation(0, 3, TimeSpan.FromSeconds(0.5));
                    rec.BeginAnimation(Rectangle.StrokeDashOffsetProperty, animation);
                    Storyboard board = new Storyboard();
                    board.Children.Add(animation);
                    Storyboard.SetTarget(animation, rec);
                    Storyboard.SetTargetProperty(animation, new PropertyPath("StrokeDashOffset"));
                    board.RepeatBehavior = RepeatBehavior.Forever;
                    board.Begin();
                }
    
                //  绘制:边框内的文字;为作出浮雕效果,文字 分:前景和背景,背景文字先画、颜色淡,前景文字后画、颜色深
                Glyphs ForeText = new Glyphs(); //  前景文字
                Glyphs BackText = new Glyphs();   //  背景文字
                ForeText.FontUri = new Uri("C:\\Windows\\Fonts\\msyh.ttc"); //文字字体
                ForeText.FontRenderingEmSize = 9;   //  文字大小
                ForeText.StyleSimulations = StyleSimulations.None;  //  字体样式,分:无字体样式、粗体、斜体、粗斜体
                ForeText.UnicodeString = Text;  //  文字 内容
                ForeText.Fill = TextColor;  //  文字 颜色
                ForeText.OriginX = TopLeft.X + 20;  //  前景文字 绘制的位置 X
                ForeText.OriginY = TopLeft.Y + 20;  //  前景文字 绘制的位置 Y
                BackText.FontUri = new Uri("C:\\Windows\\Fonts\\msyh.ttc");
                BackText.FontRenderingEmSize = 9;
                BackText.StyleSimulations = StyleSimulations.None;
                BackText.UnicodeString = Text;
                BackText.Fill = Brushes.Yellow;
                BackText.OriginX = ForeText.OriginX + 1;    //  背景文字,x 和 y 都比前景文字后移一个像素,以造成浮雕的效果
                BackText.OriginY = ForeText.OriginY + 1;   //  背景文字,x 和 y 都比前景文字后移一个像素,以造成浮雕的效果
    
                g_rect.Children.Add(rec);
                g_rect.Children.Add(BackText);
                g_rect.Children.Add(ForeText);
                lock (myGrid)
                {
                    myGrid.Children.Add(g_rect);
                    /*
                    myCanvas.Children.Add(rec); //  绘制 方框 ,作为底元素
                    myCanvas.Children.Add(BackText);    //  绘制 背景文字,作为前景文字的底元素
                    myCanvas.Children.Add(ForeText);    //  绘制 前景文字
                     */
                }
            }
            private void myGrid_Initialized(object sender, EventArgs e)
            {
                Paint(ref myGrid, new Point(0, 0), 100, 200, 1, "Hello, World!", Brushes.Black);
            }   //  end public void Paint(ref Canvas myCanvas, PointCollection PointPath)
    

    以上是“用户控件库”的代码。

    以下是WPF应用程序的代码(exe的):

            private void Window_Loaded(object sender, RoutedEventArgs e)
            {   //  绘制 演示图形
                WpfControlLibrary1.UserControl1 user1 = new UserControl1();
                MainCanvas.Children.Add(user1);
            }   //  end private void Window_Loaded(object sender, RoutedEventArgs e)
    
            private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {   //  事件:鼠标左键按下
                Mouse_inSelectedUIElement_Point = Mouse.GetPosition(e.Device.Target);
                Mouse_SelectedUIElement = (UIElement)e.Device.Target;
                //  this.Title = "Left Button Down: (" + Mouse_inUIElement_Point.X + "," + Mouse_inUIElement_Point.Y + ")";
            }   //  end private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    
            private void Window_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
            {   //  事件:鼠标左键弹起
                //  为下次做准备
                Mouse_inSelectedUIElement_Point = new Point();
                Mouse_SelectedUIElement = null;
            }   //  end private void Window_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    
            private void Window_MouseMove(object sender, MouseEventArgs e)
            {   //  事件:鼠标移动
                Point Mouse_CurrentPoint = Mouse.GetPosition(this);
                if (e.LeftButton == MouseButtonState.Pressed)
                {
                    this.Title = "Left Button Move at Canvas(" + Mouse_CurrentPoint.X + "," + Mouse_CurrentPoint.Y /*+ "); this(" + Mouse.GetPosition(this).X + "," + Mouse.GetPosition(this).Y*/ + ")";
                    if (Mouse_inSelectedUIElement_Point != null && Mouse_SelectedUIElement != null)
                    {
                        double Top = Mouse_CurrentPoint.Y - Mouse_inSelectedUIElement_Point.Y;
                        Canvas.SetTop(Mouse_SelectedUIElement, Top);
                        double Left = Mouse_CurrentPoint.X - Mouse_inSelectedUIElement_Point.X;
                        Canvas.SetLeft(Mouse_SelectedUIElement, Left);
                    }   //  end if (Mouse_inSelectedUIElement_Point != null && Mouse_SelectedUIElement != null)
                }   //  end if (e.LeftButton == MouseButtonState.Pressed)
            }   //  end 
    

    我的要求:当按下鼠标左键并移动时,实现拖动功能。

    我原先没有引入用户控件库的概念,仅将Paint下的代码添加到Canvas,而非现在的Grid时,我能实现拖动,但缺点是:选中什么拖动什么,选中Rectangle就拖动Rectangle,选中Glyphs就拖动Glyphs。而我希望在拖动Rectangle时,将Rectangle中包裹的2个Glyphs一起拖动,所以我以为加入用户控件库可以解决这个问题。

    但结果发现,不仅没有解决这个问题,反而是整个控件库都不能拖动了。我发现这个问题来源于:用户控件库没有封装自己,使得外部程序仍能识别出用户控件库中包含了Rectangle和Glyphs。

    问题:

    1)我如何在鼠标选中并拖动 1个Rectangle 或 2个Glyphs 任一元素时,使这3个元素一起移动?我想要动态的识别的代码。

    2)如何选中一个元素,使其能返回在Canvas.Children中的序号,以便我查找在这个序号下的元素,是否在所选元素的面积范围内。(假定:Children的序号越大,元素的层数越高);

    3)当我选中Rectangle时,我如何可以定位到它的父元素,在此“用户控件库”中,我选中橘黄色的Rectangle,我希望能定位到它所在Grid。

    4)我如何可以封装用户控件库,使得识别时,只知道我选中了一个控件,而不知道控件由哪些子控件组成。

    谢谢!


    2014年10月30日 7:53

全部回复