2011-06-22 23 views
7

這可能很明顯......我如何在同一個XAML文件中引用XAML元素?如何引用Grid.Row/Grid.Column中的行/列定義?

實施例:

<Grid.RowDefinitions> 
    <RowDefinition Height="661*" Name="someGridRow" /> 
    <RowDefinition Height="230*" Name="someOtherGridRow"/> 
</Grid.RowDefinitions> 

然後我定義網格內的各種控制,我想通過名稱來引用這些行,而不是由數:

<RichTextBox Grid.Row="someGridRow" ... /> 

因爲如果我上使用Grid.Row="0"很多控件,那麼當我在第一行之前添加一行時,我必須手工更改所有對Grid.Row="1"的引用。

謝謝。

編輯

感謝我一直在閱讀上XAML一點答案。

畢竟,它可以通過名字顯然是引用前一個元素:

Grid.Row="{Binding ElementName=someGridRow}" 

Grid.Row="{x:Reference someGridRow}" 

但這並不解決問題完全是因爲Grid.Row需要一個int ,而someGridRow不是一個int,它是一個System.Windows.Controls.RowDefinition。

那麼,什麼是需要的是XAML相當於

Grid.Row = grid.RowDefinitions.IndexOf(someGridRow) 

這在後面的代碼將被寫入

Grid.SetRow(richTextBox, grid.RowDefinitions.IndexOf(someGridRow)) 

或做Grid.Row的綁定屬性,對象grid,在這具有參數someGridRow的路徑"RowDefinitions.IndexOf"

PropertyPath path = new PropertyPath("RowDefinitions.IndexOf", someGridRow); 
Binding binding = new Binding() { ElementName = "grid", Path = path }; 
richTextBox.SetBinding(Grid.RowProperty, binding); 

(這其實並不在C#中工作,所以我一定是做錯了什麼,雖然上述Grid.SetRow不工作)

XAML 2009年定義<x:Arguments>調用一個帶有參數的構造函數。如果這在WPF XAML中起作用,那麼類似這樣的事情我會想辦法嗎?

<Grid.Row> 
    <Binding ElementName="grid"> 
    <Binding.Path> 
     <PropertyPath> 
     <x:Arguments> 
      RowDefinitions.IndexOf 
      <Binding ElementName="someGridRow"/> 
     </x:Arguments> 
     </PropertyPath> 
    </Binding.Path> 
    </Binding> 
</Grid.Row> 

其中<Binding ElementName="someGridRow"/>也可以通過<x:Reference Name="someGridRow"/>在2009年

+0

我想所有的,將永遠作爲屬性路徑工作,不允許像'IndexOf'方法調用。 –

+0

好吧我放棄了... – SemMike

回答

14

對於lulz:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows.Markup; 
using System.Windows.Controls; 
using System.Windows; 

namespace Test.MarkupExtensions 
{ 
    class GridDefinitionExtension : MarkupExtension 
    { 
     public string Name { get; set; } 

     public GridDefinitionExtension(string name) 
     { 
      Name = name; 
     } 

     public override object ProvideValue(IServiceProvider serviceProvider) 
     { 
      var refExt = new Reference(Name); 
      var definition = refExt.ProvideValue(serviceProvider); 
      if (definition is DefinitionBase) 
      { 
       var grid = (definition as FrameworkContentElement).Parent as Grid; 
       if (definition is RowDefinition) 
       { 
        return grid.RowDefinitions.IndexOf(definition as RowDefinition); 
       } 
       else 
       { 
        return grid.ColumnDefinitions.IndexOf(definition as ColumnDefinition); 
       } 
      } 
      else 
      { 
       throw new Exception("Found object is neither a RowDefinition nor a ColumnDefinition"); 
      } 
     } 
    } 
} 
<Grid Width="200" Height="200" 
     xmlns:me="clr-namespace:Test.MarkupExtensions"> 
    <Grid.RowDefinitions> 
     <RowDefinition Name="row1" /> 
     <RowDefinition Name="row2" /> 
    </Grid.RowDefinitions> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Name="col1" /> 
     <ColumnDefinition Name="col2" /> 
    </Grid.ColumnDefinitions> 
    <Border Background="Lime" Grid.Row="{me:GridDefinition row1}" Grid.Column="{me:GridDefinition col1}" /> 
    <Border Background="Red" Grid.Row="{me:GridDefinition row2}" Grid.Column="{me:GridDefinition col1}" /> 
    <Border Background="Yellow" Grid.Row="{me:GridDefinition row1}" Grid.Column="{me:GridDefinition col2}" /> 
    <Border Background="Blue" Grid.Row="{me:GridDefinition row2}" Grid.Column="{me:GridDefinition col2}" /> 
</Grid> 
+0

通過MarkupExtensions解決此限制的好方法。 –

+0

@Reed Copsey:謝謝:) –

+0

非常感謝!我根本不知道標記擴展或類型轉換器,現在我正在MSDN上閱讀它們。我想我實際上會使用這種東西(不僅僅是「爲了lulz」),它讓我更喜歡XAML ...... – SemMike

2

此XAML取代,不幸的是,不能正常工作。

附加的問題(即:Grid.Row)屬性被網格用來處理它們自己的佈局,以及它的設計方式,你必須把它放在數字中。

不幸的是,在插入行時更改數字在XAML開發中很常見。一種選擇 - 如果您知道要添加行,您可以放入未使用的額外「零高度」行,並稍後使用它們。

+0

謝謝。爲什麼不可能這麼簡單?就像'Grid.Row =「{x:Name someGridRow}」''應該實現... – SemMike

+0

@SemMike:我懷疑這是因爲這是如何工作的。 Grid調查Grid.Row的子節點,並且沒有真正的綁定...任何命名都必須從非類型安全標識符中完成,並且可能導致奇怪的問題。 –

+0

那麼,'Name =「someName」'你已經可以在代碼隱藏中引用這個項目,那麼爲什麼不在XAML本身呢?它在XAML中的「類型安全性」並不比在C#中低......無論如何這是不可能的,所以這一點是沒有意義的,謝謝你讓我快速擺脫困境! – SemMike

相關問題