2012-09-05 116 views
1

我對整個XAML事物頗爲陌生。輕鬆訪問控件陣列

我需要創建一個表格(網格)常量行數和列數(例如2x5)並在每個單元格中放置一個TextBlock

我該如何正確地做到這一點,所以我可以輕鬆更改單元格的數據?

例如,我想創建其接受1點的整數的函數作爲偏移量:

void fillDate(int offset) 

並填充從遞增地偏移開始細胞。

即調用與`功能fillData(3)」爲2×5將產生如下表:

| | |1|2 
3|4|5|6|7 

回答

0

這沒什麼特別的,和未來的從一個Silverlight/XAML的背景,但可能或多或少工作。您可能需要針對輕微的API差異進行調整(在不使用VS的情況下使用記事本編寫)並且未經測試,但應該爲您提供開始所需的內容。

private void fillDate(int offset) 
{ 
    int rows = 2; 
    int columns = 5; 
    int currentEntry = 1; 

    for(int rowIndex = 0; rowIndex < rows; rowIndex++) 
    { 
     for (int columnIndex = 0; columnIndex < columns; columnIndex++) 
     { 
      if (currentEntry > offset) 
      { 
       TextBlock textEntry = new TextBlock(); 
       textEntry.Text = currentEntry.ToString(); 
       Grid.SetRow(textEntry, rowIndex); 
       Grid.SetColumn(textEntry, columnIndex); 
      } 
      currentEntry++; 
     } 
    } 
} 

編輯:剛剛意識到,你可能會想,在「空」細胞無文本TextBlock的,在這種情況下,與代替內環代碼:

TextBlock textEntry = new TextBlock(); 
Grid.SetRow(textEntry, rowIndex); 
Grid.SetColumn(textEntry, columnIndex); 
if (currentEntry > offset) 
    textEntry.Text = currentEntry.ToString(); 
currentEntry++; 

編輯:基於您的發表評論,第一,當你創建你的控制,以建立網格並填充所有的文本框,並將它們存儲在某種類型的上市運行的方法:

private int Rows = 2; 
private int Columns = 5; 
private TextBlock[][] TextEntries; 

private void CreateTextBlocks() 
{ 
    TextEntries = new TextBlock[Rows][]; 
    for (int rowIndex = 0; rowIndex < rows; rowIndex++) 
    { 
     entries[rowIndex] = new string[columns]; 
     for (int columnIndex = 0; columnIndex < columns; columnIndex++) 
     { 
      TextBlock textEntry = new TextBlock(); 
      Grid.SetRow(textEntry, rowIndex); 
      Grid.SetColumn(textEntry, columnIndex); 
      myGrid.Children.Add(textEntry); 

      TextEntries[rowIndex][columnIndex] = textEntry; 
     } 
    } 
} 

隨後運行的另一種方法,以ALTE r根據需要的值:

private void fillDate(int offset) 
{ 
    int currentEntry = 1; 

    for(int rowIndex = 0; rowIndex < Rows; rowIndex++) 
    { 
     for (int columnIndex = 0; columnIndex < Columns; columnIndex++) 
     { 
      TextBlock textEntry = TextEntries[rowIndex][columnIndex] 

      if (currentEntry > offset) 
       textEntry.Text = currentEntry.ToString(); 
      else 
       textEntry.Text = String.Empty; 

      currentEntry++; 
     } 
    } 
} 
+0

與您的代碼問題(至少我認爲是您的代碼的問題! :D)是我以後無法訪問_created_'TextBlock's。即在函數的第二次調用時。 – MBZ

+0

啊,是的。我忘了將它添加到網格(myGrid.Children.Add(textEntry))。如果您想要重新使用現有的文本塊,請將其存儲在數組中,或通過網格的「兒童」屬性訪問它們。 –

+0

@MBZ我添加了另一個實現,看看它是否有幫助。 –

2

試試看這個。在這裏,您使用列表框作爲容器的項目數組和UniformGrid爲佔位符(你可以綁定的行和列到你的類的屬性的數量在運行時改變它們)

<Window x:Class=MyWindowClass ... > 
    ... 
<ListBox 
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=MyWindowClass}, Path=myItems}"> 
    <ListBox.ItemsPanel> 
     <ItemsPanelTemplate> 
      <UniformGrid Columns="{Binding Path=ColumnsInArray}"/> 
     </ItemsPanelTemplate> 
    </ListBox.ItemsPanel> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <TextBlock Text="{Binding Path=MyField}"/> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

</Window> 

和代碼你只需要改變你的集合的元素

class MyWindowClass: INotifyPropertyChanged 
{ 
    public MyWindowClass():base() 
    { 
     ... 
     InitializeComponent(); 
     myItems = new ObservableCollection<MyObject>(); 
     myItems.Add(new MyObject);// First Element 
     myItems.Add(new MyObject);// Second Element 
     ... 
     myItems.Add(new MyObject);// Last Element 
     ... 
    } 

    int columns=5; 
    public int ColumnsInArray 
    { 
     get{return columns;} 
     set {columns=value; NotifyPropertyChanged("ColumnsInArray");} 
    } 

    public ObservableCollection<MyObject> myItems 
    { 
     get{ ... } 
     set{ ... } 
    } 

setItem

void setItem(int index,MyObject newObject) 
    { 
     ... 
     myItems[index]=newObject; 
     ... 
    } 

    void setItem(int x, int y, MyObject newObject) 
    { 
     ... 
     int index = y*columns+x; 
     setItem(index,newObject); 
     ... 
    } 

INotifyPropertyChanged

public event PropertyChangedEventHandler PropertyChanged; 
    void NotifyPropertyChanged(string prop) 
    { 
     if(PropertyChanged != null) 
     PropertyChanged(this , new PropertyChangedEventArgs(prop)); 
    } 

} 

public class MyObject 
{ 
    public string MyField{get;set;} 
} 
+0

這樣做的主要思想是將ObservableCollection(相當於一維數組)映射到設置一行中元素數量的二維數組。這裏** Xcoord = index%Columns **; ** Ycoord =索引/列**; –