C# WPF中如何获得在Canvas中控件的高度和宽度 一个Border在Canvas中,因为要自动缩放,高度和宽度都是设成自动的。如果用ActualHeight和ActualWidth的话,返回的值都是零。要实现的效果是一根线的起点随着Border高度的变化而始终附着在右边的中点上。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 [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] 上边的代码不对,不是你要的效果。到底是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;}; 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); } }} 看别人的代码还是费劲啊..我觉得你的程序在原理上好像没有问题,可能出现的问题是ActualHeight这种属性只有在显示出来以后才有值。你先研究吧,今天比较忙,抱歉 搞定了。要看IsLoaded属性是否为true. panel串行求解,高手进, 请问CriticalFinalizerObject的功能是什么? 就是关于复选按钮的问题~~~~~~ 大家都进来瞧瞧! 网页资源抓取,第一次可以,第二次总超时! 播放器问题 任何正确使用LastIndexOf............? 客户端函数为何加上变量就不能执行了呢? C#里怎样从数据库读写byte型数组? 查询后,dataGrid中如何实现鼠标单击某个单元格时该单元格便出现一个comboBox控件??? c# StartIndex 不能小于 0。怎么解决。 请推荐一下学习SOCKET,多线程编程的书籍
<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]
按照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;
};
另一个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);
}
}
}
你先研究吧,今天比较忙,抱歉