一个Border在Canvas中,因为要自动缩放,高度和宽度都是设成自动的。如果用ActualHeight和ActualWidth的话,返回的值都是零。要实现的效果是一根线的起点随着Border高度的变化而始终附着在右边的中点上。

解决方案 »

  1.   

    [code=XAML]
    <Grid>
       <Canvas x:Name="cvs" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Background="Green">
          <Border BorderThickness="2" BorderBrush="Red" Margin="0" Width="{Binding ElementName=cvs, Path=ActualWidth}" Height="{Binding ElementName=cvs, Path=ActualHeight}"/>
       </Canvas>
    </Grid>
    [/code]
      

  2.   

    上边的代码不对,不是你要的效果。到底是Canvas在Border里还是Border在Canvas里?
    按照Border在Canvas里算
    [code=XAML]
    <Canvas x:Name="cvs"  VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="200,300,150,10" Background="Green">
        <Border x:Name="bdr" Height="2" BorderBrush="Red" BorderThickness="1"/>
    </Canvas>
    [/code]
    cvs.SizeChanged += delegate
    {
        //Console.WriteLine(cvs.ActualHeight);
        //Console.WriteLine(cvs.ActualWidth);
        bdr.Margin = new Thickness(5, cvs.ActualHeight / 2 - 2, 0, 0);
        bdr.Width = cvs.ActualWidth - 5;
    };
    按照Canvas在Border里面算
    [code=XAML]
    <Border x:Name="bdr" Margin="200,300,150,10" Background="Green">
        <Canvas x:Name="cvs" Height="2" Background="Red"/>
    </Border>
    [/code]bdr.SizeChanged += delegate
    {
        //Console.WriteLine(bdr.ActualHeight);
        //Console.WriteLine(bdr.ActualWidth);
        cvs.Margin = new Thickness(5, bdr.ActualHeight / 2 - 2, 0, bdr.ActualHeight / 2 - 2);
        Console.WriteLine(cvs.Margin);
        cvs.Width = bdr.ActualWidth - 5;
    };
      

  3.   

    Foxer: 谢谢回复!我之前讲得不够清楚,应该是Border在Canvas里面。但在我的程序中Border是由代码动态生成,数量是不定的。象数据库中的两个有关联的表一样,有联系的两个border中间由线段连接,从一个border右边的中点连到
    另一个border左边的中点。移动一个border时,线段也会跟着移动。下面的代码实现了Border的移动[code=XAML]<Window x:Class="BorderTest.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1"
        MouseMove="Window_MouseMove"
        MouseUp="Window_MouseUp">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition  Height="20"/>
                <RowDefinition />
            </Grid.RowDefinitions>
            <Button Name="btnGo" Click="btnGo_Click" Grid.Row="0">Go</Button>
            <Canvas x:Name="myCanvas" Grid.Row="1"  VerticalAlignment="Stretch" HorizontalAlignment="Stretch"  Background="Green">
            </Canvas>
        </Grid>
    </Window>[/code]using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;namespace BorderTest
    {
        /// <summary>
        /// Interaction logic for Window1.xaml
        /// </summary>
        public partial class Window1 : Window
        {
            bool IsMouseDown = false;
            Point mousePoint;
            object mouseCtrl = null;        public Window1()
            {
                InitializeComponent();
            }        private void myBorder_MouseDown(object sender, MouseButtonEventArgs e)
            {
                if (e.LeftButton == MouseButtonState.Pressed)
                {
                    IsMouseDown = true;
                    mousePoint = e.GetPosition(this.myCanvas);
                    mouseCtrl = sender;
                }
            }        private void Window_MouseMove(object sender, MouseEventArgs e)
            {
                if (IsMouseDown)
                {
                    if (e.LeftButton == MouseButtonState.Pressed)
                    {
                        Point theMousePoint = e.GetPosition(this.myCanvas);
                        Point theMousePointToBorder = e.GetPosition((UIElement)mouseCtrl);
                        double canvasHeight = myCanvas.ActualHeight;
                        double canvasWidth = myCanvas.ActualWidth;
                        double borderHeight = ((Border)mouseCtrl).ActualHeight;
                        double borderWidth = ((Border)mouseCtrl).ActualWidth;
                        double theLeft = theMousePoint.X - (mousePoint.X - Canvas.GetLeft(((UIElement)mouseCtrl)));
                        double theTop = theMousePoint.Y - (mousePoint.Y - Canvas.GetTop(((UIElement)mouseCtrl)));                    //Restrict border object of being dragged within canvas
                        if (theLeft < 0.0)
                            theLeft = 0.0;
                        if (theLeft > (canvasWidth - borderWidth))
                            theLeft = canvasWidth - borderWidth;
                        if (theTop < 0.0)
                            theTop = 0.0;
                        if (theTop > (canvasHeight - borderHeight))
                            theTop = canvasHeight - borderHeight;                    Canvas.SetLeft((UIElement)mouseCtrl, theLeft);
                        Canvas.SetTop((UIElement)mouseCtrl, theTop);                    mousePoint = theMousePoint;
                    }
                }
            }        private void Window_MouseUp(object sender, MouseButtonEventArgs e)
            {
                if (IsMouseDown)
                {
                    IsMouseDown = false;
                }
            }        private void btnGo_Click(object sender, RoutedEventArgs e)
            {
                Border myBorder = new Border();
                myBorder.Background = Brushes.LightBlue;
                myBorder.BorderBrush = Brushes.Black;
                myBorder.BorderThickness = new Thickness(2);
                myBorder.CornerRadius = new CornerRadius(10);
                myBorder.Padding = new Thickness(10.0);
                myBorder.AllowDrop = true;
                myBorder.MouseDown += new MouseButtonEventHandler(myBorder_MouseDown);            TextBlock myText = new TextBlock();
                myText.Text = "Test Message";            myBorder.Child = myText;            Canvas.SetLeft(myBorder, 100);
                Canvas.SetTop(myBorder, 20);            // Add a Line Element
                Line myLine = new Line();
                myLine.Stroke = System.Windows.Media.Brushes.Red;
                myLine.X1 = 1;
                myLine.X2 = 100;
                myLine.Y1 = 1;
                myLine.Y2 = 100;
                myLine.HorizontalAlignment = HorizontalAlignment.Left;
                myLine.VerticalAlignment = VerticalAlignment.Center;
                myLine.StrokeThickness = 2;            Canvas.SetLeft(myLine, 150);
                Canvas.SetTop(myLine, 30);            myCanvas.Children.Add(myBorder);
                myCanvas.Children.Add(myLine);
            }
        }
    }
      

  4.   

    看别人的代码还是费劲啊..我觉得你的程序在原理上好像没有问题,可能出现的问题是ActualHeight这种属性只有在显示出来以后才有值。
    你先研究吧,今天比较忙,抱歉
      

  5.   

    搞定了。要看IsLoaded属性是否为true.