2009-11-02 2 views
4

У меня есть Grid, который представляет некоторые данные, и мне нужен Canvas, чтобы наложить поверх него макет некоторых строк. Canvas находится внутри собственного UserControl.WPF Canvas and Grid overlay

Проблема заключается в том, что Canvas и его содержимое должны авторезистироваться, когда размер Grid изменяет размеры и ширину.

Я добавил Canvas внутри ViewBox, но это не помогло. Когда Grid изменяет размер, Canvas нет. Целью Canvas является наложение линейчатой ​​функциональности поверх сетки.

Ждем ваших решений.

EDIT

Я не могу использовать стиль на сетке, чтобы заменить холст, потому что сетка отображается различная информация, чем холст делает. Подумайте об этом, как диаграммы, в которых есть бар колонны различных размеров (в моем случае сетки), а дни линии в виде наложения (только как Gannt Chart)

Мой код:

taxCanvas = new TimeAxis(); 
    Grid.SetRowSpan(taxCanvas, GRightMain.RowDefinitions.Count); 
    Grid.SetColumnSpan(taxCanvas, GRightMain.ColumnDefinitions.Count); 

    Grid.SetColumn(taxCanvas, 0); 
    Grid.SetRow(taxCanvas, 0); 


    Grid.SetZIndex(taxCanvas, -1); 

    taxCanvas.Height = GRight.ActualHeight; 
    taxCanvas.Width = GRight.ActualWidth; 

    GRightMain.Children.Add(taxCanvas); 

TimeAxis - это мое пользовательское управление холстом, GRightMain - это сетка, которая содержит как мой холст, так и сетку с содержимым (Gright) в той же строке и столбце.

Надеется, что это помогает

ответ

1

Вы можете использовать привязку к «привязать» размер Canvas и размер Grid друг к другу. Поэтому, когда размер Grid изменится, Canvas будет делать это автоматически.

Также вы можете использовать Converter для привязки, которую вы должны вычислить и смещать как расстояние от границы.

Связывание в WPF всегда является хорошей идеей, поэтому убедитесь, что вы знаете основы того, как это работает.

В любом случае вы всегда можете сделать это в коде-Behind (C#/VB) в Size-Event. Просто определите размер одного элемента управления и установите его в другое. Как получить actualHeight свойство Grid и установить его на высота свойство холста.

Может быть, это даст вам представление: http://blogs.msdn.com/bencon/archive/2006/05/10/594886.aspx или http://www.switchonthecode.com/tutorials/wpf-tutorial-binding-converters

1

Что это такое, что ваш пытаются сделать? Если вы просто хотите добавить сетки в сетку, вы можете сделать это, установив стили like this. В качестве альтернативы вы можете использовать Adorner s. Они предназначены для украшения/украшения элементов на отдельном слое. Хорошая вещь об украшателях заключается в том, что, хотя они находятся на отдельном слое, они сохраняют синхронизацию (размер, положение, трансформацию) с элементом, который они украшают.

4

Холст, на мой взгляд, определенно неправильный подход.

Я настоятельно рекомендую посмотреть нарушителей. Вы можете создать индивидуального рекламодателя, чтобы сделать именно это.

Adorner - это в основном «неинтерактивное окно», которое находится поверх всех UIElements. Он позволяет делать все, что угодно (создавать элементы управления, рисовать вещи и т. Д.), Которые будут отображаться поверх самого элемента управления.

Изображение деревянный журнальный столик с кусочком прозрачного стекла поверх него. Если вы нарисуете прозрачное стекло, вы все равно увидите кофейный столик. Единственное различие заключалось в том, что вы действительно можете достичь прямо через прозрачное стекло на кофейном столике и коснуться самого дерева.

Ненавижу публикацию ссылок MSDN ... но ... ах. В этом случае было бы хорошее начало:

http://msdn.microsoft.com/en-us/library/ms743737.aspx

EDIT:

я бросил что-то вместе быстро. Надеюсь, это поможет?

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:loc="clr-namespace:WpfApplication1" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
    <loc:GridWithRulerxaml></loc:GridWithRulerxaml> 
    <Button Height="20" Width="50" >Click me</Button> 
    <TextBox Width="150" Height="25" HorizontalAlignment="Left">This is a text box</TextBox> 
    </Grid> 
</Window> 

UserControl:

<UserControl x:Class="WpfApplication1.GridWithRulerxaml" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"> 
    <Grid> 

    </Grid> 
</UserControl> 

UserControl КОД-ЗА:

using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Documents; 

namespace WpfApplication1 
{ 
    /// <summary> 
    /// Interaction logic for GridWithRulerxaml.xaml 
    /// </summary> 
    public partial class GridWithRulerxaml : UserControl 
    { 
    public GridWithRulerxaml() 
    { 
     InitializeComponent(); 

     //Loaded event is necessary as Adorner is null until control is shown. 
     Loaded += GridWithRulerxaml_Loaded; 

    } 

    void GridWithRulerxaml_Loaded(object sender, RoutedEventArgs e) 
    { 
     var adornerLayer = AdornerLayer.GetAdornerLayer(this); 
     var rulerAdorner = new RulerAdorner(this); 
     adornerLayer.Add(rulerAdorner); 
    } 
    } 
} 

В конце концов Adorner САМ:

using System.Windows; 
using System.Windows.Documents; 
using System.Windows.Media; 

namespace WpfApplication1 
{ 
    public class RulerAdorner : Adorner 
    { 
    private FrameworkElement element; 
    public RulerAdorner(UIElement el) : base(el) 
    { 
     element = el as FrameworkElement; 
    } 

    protected override void OnRender(System.Windows.Media.DrawingContext drawingContext) 
    { 
     base.OnRender(drawingContext); 

     double height = element.ActualHeight; 
     double width = element.ActualWidth; 

     double linesHorizontal = height/50; 
     double linesVertical = width/50; 

     var pen = new Pen(Brushes.RoyalBlue, 2) { StartLineCap = PenLineCap.Triangle, EndLineCap = PenLineCap.Triangle }; 

     int offset = 0; 

     for (int i = 0; i <= linesVertical; ++i) 
     { 
     offset = offset + 50; 
     drawingContext.DrawLine(pen, new Point(offset, 0), new Point(offset, height)); 
     } 

     offset = 0; 

     for (int i = 0; i <= linesHorizontal; ++i) 
     { 
     offset = offset + 50; 
     drawingContext.DrawLine(pen, new Point(0, offset), new Point(width, offset)); 
     } 
    } 
    } 
} 

Если вы хотите, чтобы я более подробно рассказать о сам код дайте мне знать.

Я подтвердил, что это нарисует сетку поверх всего, что находится на вашей главной странице. Вы все равно должны взаимодействовать с тем, что ниже.

+0

wow Я просто понял, что это было с ноября 2009 года – tronious