【发布时间】:2015-09-03 03:01:25
【问题描述】:
这是我第一次发帖,请放心...
肯定有一些帖子展示了如何将线连接到块,但这个有点不同。网格动态放置在画布上。我想要一条线将按下按钮的网格连接到放置在画布上的新网格。但是下面的代码不起作用。我已经为此苦苦挣扎了很长时间。
只是偶然我发现按钮事件处理程序中抛出的消息框将允许它工作。我认为这是来自在不同时间运行的线程,但是在弄乱了 task.delay/thread.sleep/async/await 之后我找不到解决方案。
我正在使用自定义类,因为这是大型程序的精简版本,我希望在我的示例中具有类似的功能以反映可能的错误,但省略不必要的部分。
我将其用作最后的手段,在此先感谢您提供的任何帮助。首先是CS代码
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
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 WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Grid1 g = myCanvas.CreateGrid();
ContentControl1 cc = myCanvas.CreateCC();
Button1 b = myCanvas.CreateButton1();
Grid1.SetColumn(cc, 0);
Grid1.SetRow(cc, 0);
Grid1.SetColumn(b, 1);
Grid1.SetRow(b, 1);
g.Children.Add(cc);
g.Children.Add(b);
Canvas1.SetLeft(g, 500);
Canvas1.SetTop(g, 5);
myCanvas.Children.Add(g);
}
}
public class Button1 : Button
{
protected override void OnClick()
{
Grid1 old_g = (Grid1)VisualTreeHelper.GetParent(this as DependencyObject);
Canvas1 cnv = (Canvas1)VisualTreeHelper.GetParent(old_g as DependencyObject);
Grid1 g = cnv.CreateGrid();
ContentControl1 cc = cnv.CreateCC();
Button1 b = cnv.CreateButton1();
Grid1.SetColumn(cc, 0);
Grid1.SetRow(cc, 0);
Grid1.SetColumn(b, 1);
Grid1.SetRow(b, 1);
g.Children.Add(cc);
g.Children.Add(b);
Canvas1.SetLeft(g, 500);
Canvas1.SetTop(g, cnv.Children.Count * 120);
cnv.Children.Add(g);
cnv.ConnectGrids(old_g, g);
}
}
public class Canvas1 : Canvas
{
public Grid1 CreateGrid()
{
Grid1 g = new Grid1() { Width = 100, Height = 20, Background = Brushes.White };
g.HorizontalAlignment = HorizontalAlignment.Center;
g.VerticalAlignment = VerticalAlignment.Center;
g.ShowGridLines = false;
ColumnDefinition colDef1 = new ColumnDefinition();
ColumnDefinition colDef2 = new ColumnDefinition() { Width = new GridLength(20) };
g.ColumnDefinitions.Add(colDef1);
g.ColumnDefinitions.Add(colDef2);
RowDefinition rowDef1 = new RowDefinition();
g.RowDefinitions.Add(rowDef1);
return g;
}
public ContentControl1 CreateCC()
{
ContentControl1 cc = new ContentControl1()
{
VerticalContentAlignment = VerticalAlignment.Stretch,
HorizontalContentAlignment = HorizontalAlignment.Stretch,
BorderBrush = Brushes.BlueViolet,
};
return cc;
}
public Button1 CreateButton1()
{
Button1 b = new Button1()
{
VerticalContentAlignment = VerticalAlignment.Stretch,
HorizontalContentAlignment = HorizontalAlignment.Stretch,
BorderBrush = Brushes.Red
};
return b;
}
public void ConnectGrids(Grid1 g1, Grid1 g2)
{
Canvas1 cnv = (Canvas1)VisualTreeHelper.GetParent(g1 as DependencyObject);
Transform transform1 = (Transform)g1.TransformToVisual(cnv as Visual);
Transform transform2 = (Transform)g2.TransformToVisual(cnv as Visual);
Point StartPoint1 = transform1.Transform(new Point(g1.Width, g1.Height / 2.0));
Point EndPoint1 = transform2.Transform(new Point(g2.Width, g2.Height / 2.0));
var lineGeometry = new LineGeometry()
{
StartPoint = StartPoint1,
EndPoint = EndPoint1
};
var path = new Path()
{
Data = lineGeometry,
Stroke = new SolidColorBrush(Colors.Black),
};
cnv.Children.Add(path);
}
}
public class ContentControl1 : ContentControl
{
}
public class Grid1 : Grid
{
}
}
然后是 xaml:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local ="clr-namespace:WpfApplication1"
Title="MainWindow" Height="1000" Width="1000">
<DockPanel>
<Button DockPanel.Dock="Top" Width="100" Height="20" Content="Start" Click="Button_Click"/>
<ScrollViewer HorizontalScrollBarVisibility="Visible" Width="901" x:Name="_scrollViewer" Margin="0,5,0,25">
<local:Canvas1 Background="Gray" Height="1000" Width="1000" x:Name="myCanvas"/>
</ScrollViewer>
</DockPanel>
</Window>
如何才能成功地将网格与路径连接起来?
【问题讨论】:
-
删除所有内容并使用正确的 XAML 和数据绑定。
-
如果你的意思是……让对象的创建成为静态的,那就违背了这个项目的目的。如果有一种方法可以通过 xaml 动态创建对象,我很乐意学习。但是每次点击一个按钮,我都想在画布上创建更多对象。
-
不,我并不是要以任何方式使对象的“创建”成为“静态”。我的意思是使用正确的 XAML 和 DataBinding。请参阅我的示例,了解如何正确执行此操作here
标签: c# wpf multithreading canvas