2011-03-11 44 views
1

想象一下具有網格疊加的表單設計器,它將表示平面上的座標。我試圖將自定義ItemsControl中的網格疊加層的屬性綁定到Canvas自定義控件TemplateBinding問題

網格使用VisualBrush創建。 VisualBrushViewboxViewport在代碼中綁定到Rect,以及RectangleHeightWidth用於顯示網格圖塊。然而,當控件顯示時,網格貼片似乎是「無限小」(網格只是灰色),因爲如果我放大網格,程序最終會抓住,無法呈現它。顯然,這不是我要去的效果。

<Style TargetType="{x:Type Controls:FormControl}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type Controls:FormControl}"> 
       <Border Background="White" 
         BorderBrush="Black" 
         BorderThickness="1" 
         Padding="49"> 
        <Grid Height="{TemplateBinding CanvasHeight}" 
          Width="{TemplateBinding CanvasWidth}"> 
         <Grid.Background> 
          <!--"0,0,6,11.3266666666667"--> 
          <VisualBrush TileMode="Tile" 
             Viewbox="{TemplateBinding GridUnitViewbox}" 
             ViewboxUnits="Absolute" 
             Viewport="{TemplateBinding GridUnitViewbox}" 
             ViewportUnits="Absolute"> 
           <VisualBrush.Visual> 
            <Rectangle Height="{Binding RelativeSource={RelativeSource TemplatedParent},Path=GridUnitViewbox.Height}" 
               HorizontalAlignment="Left" 
               Opacity="{TemplateBinding GridOpacity}" 
               Stroke="Black" 
               StrokeThickness=".1" 
               VerticalAlignment="Top" 
               Width="{Binding RelativeSource={RelativeSource TemplatedParent},Path=GridUnitViewbox.Width}" /> 
           </VisualBrush.Visual> 
          </VisualBrush> 
         </Grid.Background> 
         <ItemsPresenter /> 
        </Grid> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
    <Setter Property="ItemsPanel"> 
     <Setter.Value> 
      <ItemsPanelTemplate> 
       <Canvas /> 
      </ItemsPanelTemplate> 
     </Setter.Value> 
    </Setter> 
    <Setter Property="ItemContainerStyle"> 
     <Setter.Value> 
      <Style TargetType="Controls:FormControlItem"> 
       <Setter Property="Canvas.Left" 
         Value="{Binding Path=X}" /> 
       <Setter Property="Canvas.Top" 
         Value="{Binding Path=Y}" /> 
      </Style> 
     </Setter.Value> 
    </Setter> 
</Style> 

任何想法我在做什麼錯在這裏。謝謝。

編輯: 也許更多的背景我可以把它放在更好的背景下。我爲稅務準備軟件公司工作,目前,我們的表格部門使用爲我們的產品編寫的標記(如百萬年前)創建替代表格。用這種方式創建表單有點麻煩,所以我正在爲它們開發一個可視化的「表單設計器」,它將更像一個所見即所得的設計器,並將設計器的內容翻譯成標記。那麼,美國國稅局是真正的肛門,它的形式完全取決於原來的位置,所以有一個非常鬆散的標準,可以在表格上放置「網格疊加」以確定事情需要去的地方;基本上是各種座標平面。

FormControl實質上是這些替代形式之一的可視化表示形式,即設計師將要創建的形式之一。

CanvasWidthCanvasHeight是依賴屬性的CLR包裝。通過乘以GridUnitViewbox的尺寸,他們在OnApplyTemplate()中被分配值,然而許多網格瓦片​​需要在網格覆蓋中,即,大多數情況下爲78x63格。

名稱CanvasWidthCanvasHeight我想可能是他們不指Canvas控制有點誤導,但對Grid容納Canvas(可能需要更改命名約定)。也就是說,CanvasHeight,CanvasWidthGridUnitViewbox不依賴於任何控件的屬性,而是在OnApplyTemplate()中完成的計算。

public static readonly DependencyProperty GridUnitViewboxProperty = 
     DependencyProperty.Register("GridUnitViewbox", typeof(Rect), typeof(FormControl), 
     new FrameworkPropertyMetadata(new Rect(0, 0, 6, 11.3266666666667), 
      FrameworkPropertyMetadataOptions.AffectsMeasure | 
      FrameworkPropertyMetadataOptions.AffectsParentMeasure)); 

    public override void OnApplyTemplate() 
    { 
     base.OnApplyTemplate(); 

     FormattedText formattedText = new FormattedText(
      "X", 
      CultureInfo.GetCultureInfo("en-us"), 
      FlowDirection.LeftToRight, 
      new Typeface("Courier New"), 
      10, 
      Brushes.Black); 

     this.GridUnitViewbox = new Rect(0, 0, formattedText.WidthIncludingTrailingWhitespace, formattedText.Height); 

     if (this.PageLayout == PageLayoutType.Landscape) 
     { 
      this.CanvasHeight = this.GridUnitViewbox.Height * 48.0; 
      this.CanvasWidth = this.GridUnitViewbox.Width * 109.0; 
     } 
     if (this.PageLayout == PageLayoutType.Portrait) 
     { 
      this.CanvasHeight = this.GridUnitViewbox.Height * 63.0; 
      this.CanvasWidth = this.GridUnitViewbox.Width * 78.0; 
     } 
    } 

Grid控制實際上是做什麼我想它做的事。它內部的VisualBrushRectangle要麼沒有正確綁定,要麼沒有正確更新。 <Grid.Background>正下方的註釋是我在使用VisualBrushViewboxViewport以及Rectangle的尺寸之前對其進行的硬編碼測試值,它在視覺上確切地說明了我要做的事情。我也確認了6和11.3266666666667實際上是運行期間GridUnitViewbox尺寸的值。

但我有一種感覺,即綁定產生'0,0,0,0',但是,因爲網格覆蓋只是一個灰色陰影,正在消耗大量的資源;實際上,如果您放大該程序,就會鎖定該程序。如您所見,在代碼中,我嘗試將AffectsMeasureAffectsParentMeasure添加到依賴項屬性的元數據選項中,希望在更新GridUnitViewbox的維度後UI可能沒有正確更新,但我錯了。我不知道還有什麼可以的。

+0

你需要更具體,並打破你的問題。人們懷疑是否會花時間去瀏覽大量的XAML標記。 – 2011-03-11 05:36:20

回答

1

好吧,以防萬一遇到類似問題,我找到了解決方法。顯然VisualBrush有點挑剔TemplateBinding s。我調整了XAML正是如此,它解決了這個問題:

<VisualBrush TileMode="Tile" 
      Viewbox="{Binding RelativeSource={RelativeSource TemplatedParent},Path=GridUnitViewbox}" 
      ViewboxUnits="Absolute" 
      Viewport="{Binding RelativeSource={RelativeSource TemplatedParent},Path=GridUnitViewbox}" 
      ViewportUnits="Absolute"> 

這裏是article那裏我得到了來自信息。

0

什麼是CanvasWidth和CanvasHeight?他們是否定義?

此外,我相信一個畫布沒有大小,除非明確指定。綁定到它時,寬度/高度可能爲零。

嘗試ActualWidth和ActualHeight或渲染過程後的畫布以查看它們是否包含任何值,但afaik它們不會提供,除非您提供。

+0

希望編輯清除了一些東西。 – SirBeastalot 2011-03-11 15:40:50