Is there a way that I could get the XY co-ordinates of TreeViewItems in a TreeView?
-
Hi All, I am working a project where I need to draw lines between two TreeViews to map the elements. For this, I need the XY co=ordinates of the TreeViewItem. Is there a way to get the XY co-ordinates? If I can, how to get it? Thanks in advance.
[Venkatesh Mookkan] My: Website | Yahoo Group | Blog Spot
-
Hi All, I am working a project where I need to draw lines between two TreeViews to map the elements. For this, I need the XY co=ordinates of the TreeViewItem. Is there a way to get the XY co-ordinates? If I can, how to get it? Thanks in advance.
[Venkatesh Mookkan] My: Website | Yahoo Group | Blog Spot
VisualTreeHelper.GetDescendantBounds gives you the bounding rectangle. I tested drawing a line by transforming the result to screen then back to the container of the TreeViews. The more difficult part is how you draw the lines, you could put both TreeViews in a canvas and add line objects, or use an adorner, both seemed to work ok. I set the lines coordinates by using CompositionTarget.Rendering so they are always up to date if items move.
<Canvas x:Name="canvas">
<Grid Height="{Binding Path=ActualHeight, ElementName=canvas}" Width="{Binding Path=ActualWidth, ElementName=canvas}">
<Grid.RowDefinitions>
<RowDefinition Height="8*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<TreeView x:Name="tree" Margin="1.5,0" Grid.Column="0">
<TreeViewItem Header="A" IsExpanded="True">
<TreeViewItem Header="1" x:Name="item1" />
<TreeViewItem Header="2" />
<TreeViewItem Header="3" />
</TreeViewItem>
</TreeView>
<GridSplitter Width="8" />
<TreeView x:Name="tree2" Grid.Column="1">
<TreeViewItem Header="B" IsExpanded="True">
<TreeViewItem Header="1" />
<TreeViewItem Header="2" />
<TreeViewItem Header="3" x:Name="item2" />
</TreeViewItem>
</TreeView>
<Button Click="button1_Click" Grid.ColumnSpan="2" Grid.Row="1">Add Item</Button>
</Grid>
</Canvas>private Line line;
public Window1()
{
InitializeComponent();
Loaded += Window1_Loaded;
}void Window1_Loaded(object sender, RoutedEventArgs e)
{
line = new Line {Stroke = Brushes.Red,StrokeThickness = 2};
canvas.Children.Add(line);
CompositionTarget.Rendering +=CompositionTarget_Rendering;
}void CompositionTarget_Rendering(object sender, EventArgs e)
{
Rect r1 = VisualTreeHelper.GetDescendantBounds(item1);
Rect r2 = VisualTreeHelper.GetDescendantBounds(item2);Point p1 = canvas.PointFromScreen(item1.Poin
-
VisualTreeHelper.GetDescendantBounds gives you the bounding rectangle. I tested drawing a line by transforming the result to screen then back to the container of the TreeViews. The more difficult part is how you draw the lines, you could put both TreeViews in a canvas and add line objects, or use an adorner, both seemed to work ok. I set the lines coordinates by using CompositionTarget.Rendering so they are always up to date if items move.
<Canvas x:Name="canvas">
<Grid Height="{Binding Path=ActualHeight, ElementName=canvas}" Width="{Binding Path=ActualWidth, ElementName=canvas}">
<Grid.RowDefinitions>
<RowDefinition Height="8*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<TreeView x:Name="tree" Margin="1.5,0" Grid.Column="0">
<TreeViewItem Header="A" IsExpanded="True">
<TreeViewItem Header="1" x:Name="item1" />
<TreeViewItem Header="2" />
<TreeViewItem Header="3" />
</TreeViewItem>
</TreeView>
<GridSplitter Width="8" />
<TreeView x:Name="tree2" Grid.Column="1">
<TreeViewItem Header="B" IsExpanded="True">
<TreeViewItem Header="1" />
<TreeViewItem Header="2" />
<TreeViewItem Header="3" x:Name="item2" />
</TreeViewItem>
</TreeView>
<Button Click="button1_Click" Grid.ColumnSpan="2" Grid.Row="1">Add Item</Button>
</Grid>
</Canvas>private Line line;
public Window1()
{
InitializeComponent();
Loaded += Window1_Loaded;
}void Window1_Loaded(object sender, RoutedEventArgs e)
{
line = new Line {Stroke = Brushes.Red,StrokeThickness = 2};
canvas.Children.Add(line);
CompositionTarget.Rendering +=CompositionTarget_Rendering;
}void CompositionTarget_Rendering(object sender, EventArgs e)
{
Rect r1 = VisualTreeHelper.GetDescendantBounds(item1);
Rect r2 = VisualTreeHelper.GetDescendantBounds(item2);Point p1 = canvas.PointFromScreen(item1.Poin
Dave, Thanks for the working sample. The sample gives me an idea to start with.
[Venkatesh Mookkan] My: Website | Yahoo Group | Blog Spot