2009-02-20 46 views
2

任何人都可以告訴我是否可以創建數據並將其添加到未綁定的WPF Toolkit數據網格中。手動創建未綁定的數據網格

如果它實際上是可以做到的,有人可以請提供以下的例子:

編程: 創建DataGrid 創建datagridtextcolumn 的datagridtextcolumn添加到DataGrid 創建datagridrow 集數據網格列的文本爲「test」行 將datagridrow添加到數據網格

我想創建一個未綁定的數據網格。我的理由是,我想創建一個模板列,其中包含多個不同類型和數字的控件 - 2個複選框,4個單選按鈕,5個複選框等 - 它們在運行時動態添加,並且由於類型和數量未知,因此無法想到一個數據綁定的方法。我很高興不受約束地工作。

預先感謝您!

[編輯:我還沒有找到一個合適的回答這個問題,並開始一個賞金]

回答

1

您可以使用UserControl來創建所需的控件。

Window1.xaml(片斷)

<dg:DataGrid ItemsSource="{Binding}" CanUserAddRows="False" AutoGenerateColumns="False"> 
    <dg:DataGrid.Columns> 

     <dg:DataGridTemplateColumn Header="Test" MinWidth="100"> 
      <dg:DataGridTemplateColumn.CellTemplate> 
       <DataTemplate> 
        <my:ControlA Foo="{Binding}"></my:ControlA> 
       </DataTemplate> 
      </dg:DataGridTemplateColumn.CellTemplate> 
     </dg:DataGridTemplateColumn> 

    </dg:DataGrid.Columns> 
</dg:DataGrid> 

Window1.xaml.cs

public partial class Window1 : Window 
{ 
    List<Foo> _items = new List<Foo>(); 

    public Window1() 
    { 
     InitializeComponent(); 

     _items.Add(new Foo { CheckBoxCount = 2, TextBoxCount = 1 }); 
     _items.Add(new Foo { CheckBoxCount = 3, TextBoxCount = 0 }); 

     DataContext = _items; 
    } 
} 

ControlA.xaml

<UserControl x:Class="Demo.ControlA" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <StackPanel x:Name="_placeHolder"> 
    </StackPanel> 
</UserControl> 

ControlA.xaml.cs

public partial class ControlA : UserControl 
{ 
    public ControlA() 
    { 
     InitializeComponent(); 

     Loaded += new RoutedEventHandler(ControlA_Loaded); 
    } 

    void ControlA_Loaded(object sender, RoutedEventArgs e) 
    { 
     if (Foo != null) 
     { 
      for (int it = 0; it < Foo.CheckBoxCount; it++) 
       _placeHolder.Children.Add(new CheckBox()); 

      for (int it = 0; it < Foo.TextBoxCount; it++) 
       _placeHolder.Children.Add(new TextBox()); 
     } 
    } 

    public static readonly DependencyProperty FooProperty = 
     DependencyProperty.Register("Foo", typeof(Foo), typeof(ControlA)); 

    public Foo Foo 
    { 
     get { return (Foo)GetValue(FooProperty); } 
     set { SetValue(FooProperty, value); } 
    } 
} 

Foo.cs

public class Foo 
{ 
    public int TextBoxCount { get; set; } 
    public int CheckBoxCount { get; set; } 
} 

希望這有助於。

P.S.應該可以將refactor DataGridTemplateColumn轉換爲單獨的UserControl。

1

我從來沒有使用網格不綁定的東西。

看的根本原因,可同時仍使用數據綁定來解決。

例如: 如果您使用ViewModel類爲您提供網格綁定的對象,那麼您可以使該類的某個方面成爲各種控件的可見性設置器。

在對象,你有這樣的:

Public ReadOnly Property CheckboxAVisibility As Windows.Visibility 
    Get 
    ' Do Logic 
    Return Visiblity 
    End Get 
End Property 

而在XAML,你會怎麼做:

<CheckBox IsChecked="{Binding IsBoxAChecked}" Visibility={Binding CheckboxAVisibility}" /> 

這也讓事情變得簡單,你就可以通過修改該行內的其他控件來修改各種控件的可見性(例如,取消選中CheckboxA導致RadioButton B,出現C & D)。

第二種選擇是在網格中僅列出「標題」信息,並且當用戶雙擊一行時,您將在輔助面板或窗口中顯示帶有可編輯方面的編輯器(類似於MVC編輯作品)。由於

編輯評論

這裏的另一項建議,而不是一個DataGrid,使用一個StackPanel。對於您需要的每一行,您可以添加一個網格面板或堆棧面板或類似的東西,根據您的規則在運行時創建。例如:

XAML:

<StackPanel Name="stkItems" Orientation="Vertical" /> 

代碼:

Public Sub AddItems(dt as DataTable) 
    For Each row As DataRow in dt.Rows 
    Select Case row("Which") 
      Case 1: 
      Dim i As New Checkbox 
      i.Content = "Foo" 
      i.IsChecked = row("Content") 
      stkItems.Children.Add(i) 
      Case 2: 
       Dim i as New TextBox 
       i.Text = row("Content") 
       stkItems.Children.Add(i) 
    End Select 
    Next 
End Sub 

這是非常簡單的,你可以做的事情,例如有,你可以使用,或只是建立一個預定義的用戶控件將一堆控件放入一個編程定義的容器中,然後將其添加到StackPanel中

+0

視圖模型方法是我考慮過的事情。然而,我無法弄清楚如何克服任何給定行不知道的基本障礙,我將擁有哪種類型的控件以及我將擁有多少控件。在那裏硬編碼一定數量並設置其可見度是不可能的。 – 2009-02-23 15:56:21

+0

您可能更樂意迴避datagrid然後 - 看看我的編輯 – 2009-02-24 19:33:03

0

我已經創建了一個簡單的DataGridUnboundedColumn類,它是從DataGridBoundColumn派生的,可用於爲單元格提供FrameworkElement的自定義文本。

您只需訂閱CellFormating事件並將EventArgs中的CellElement設置爲將顯示的自定義元素。也可以在EventArgs中設置CellText - 在這種情況下,具有CellText的TextBlock將顯示在網格中。

下面的例子演示瞭如何使用它:

XAML:

<dg:DataGrid Name="DataGrid1" AutoGenerateColumns="False"> 
    <dg:DataGrid.Columns> 
     <dg:DataGridTextColumn Header="Name" Binding="{Binding Path=Name}"/> 
     <myColumn:DataGridUnboundedColumn x:Name="AddressColumn" Header="Address" /> 
    </dg:DataGrid.Columns> 
</dg:DataGrid> 

CODE:

public MyPage() 
    { 
     InitializeComponent(); 

     AddressColumn.CellFormating += new UnboundedColumnEventHandler(AddressColumn_CellFormating); 
    } 

    void AddressColumn_CellFormating(object sender, UnboundedColumnEventArgs e) 
    { 
     IPerson person; 

     person= e.DataItem as IPerson; 

     if (person!= null) 
      e.CellText = string.Format("{0}, {1} {2}", person.Address, person.PostalCode, person.City); 
    } 

的DataGridUnboundedColumn實現是在這裏:

class DataGridUnboundedColumn : DataGridBoundColumn 
{ 
    public event UnboundedColumnEventHandler CellFormating; 

    public DataGridUnboundedColumn() 
    { 
     this.IsReadOnly = true; 
    } 

    protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem) 
    { 
     return null; 
    } 

    protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem) 
    { 
     FrameworkElement shownElement; 
     UnboundedColumnEventArgs eventArgs; 

     if (CellFormating == null) 
      return null; 


     eventArgs = new UnboundedColumnEventArgs(cell, dataItem); 

     // call the event 
     CellFormating(this, eventArgs); 

     shownElement = null; 

     // check the data set in the eventArgs 
     if (eventArgs.CellElement != null) 
     { 
      // show the set eventArgs.CellElement 
      shownElement = eventArgs.CellElement; 
     } 
     else if (eventArgs.CellText != null) 
     { 
      // show the CellText in TextBlock 
      TextBlock textBlock = new TextBlock(); 
      textBlock.Text = eventArgs.CellText; 

      shownElement = textBlock; 
     } 
     else 
     { 
      // nothing set 
     } 

     return shownElement; 
    } 
} 

public delegate void UnboundedColumnEventHandler(object sender, UnboundedColumnEventArgs e); 

public class UnboundedColumnEventArgs : EventArgs 
{ 
    public DataGridCell Cell { get; set; } 
    public object DataItem { get; set; } 

    /// <summary> 
    /// The subscriber of the event can set the CellText. 
    /// In this case the TextBlock is used to display the text. 
    /// NOTE that if CellElement is not null, the CellText will not be used but insted a CellElement will be shown 
    /// </summary> 
    public string CellText { get; set; } 

    /// <summary> 
    /// The subscribed can set the FrameworkElement that will be shown for this cell. 
    /// If the CellElement is null, the CellText will be used to show the TextBlock 
    /// </summary> 
    public FrameworkElement CellElement { get; set; } 

    public UnboundedColumnEventArgs() 
     : base() 
    { } 

    public UnboundedColumnEventArgs(DataGridCell cell, object dataItem) 
     : base() 
    { 
     Cell = cell; 
     DataItem = dataItem; 
    } 
}