有人能告诉我是否可以创建数据并将数据添加到未绑定的WPF Toolkit数据网格。
如果事实上可以做,有人可以提供以下示例:
编程: 创建一个数据网格 创建datagridtextcolumn 将datagridtextcolumn添加到datagrid 创建一个datagridrow 将行的datagridtextcolumn的文本设置为“test” 将datagridrow添加到datagrid
我想创建一个未绑定的数据网格。我的理由是我想创建一个模板列,其中包含多个不同类型和数字的控件 - 2个复选框,4个单选按钮,5个复选框等 - 这些都是在运行时动态添加的,因为类型和编号未知也无法想到一种数据绑定方式。我很乐意无拘无束地工作。
提前谢谢!
[编辑:我还没有找到这个问题的合适答案并开始获得奖励]
答案 0 :(得分: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会导致RadioButtons B,C&amp; D出现)。
第二个选项是在网格中仅列出“标题”信息,当用户双击一行时,您将在辅助面板或窗口中显示带有可编辑方面的编辑器(类似于MVC编辑的工作方式) )。
因评论而修改
这是另一个建议,而不是数据网格,使用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
答案 1 :(得分: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。
答案 2 :(得分:0)
我创建了一个简单的DataGridUnboundedColumn类,它派生自DataGridBoundColumn,可用于为单元格提供FrameworkElement的自定义文本。
您只需订阅CellFormating事件,并将EventArgs中的CellElement设置为将要显示的自定义元素。也可以在EventArgs中设置CellText - 在这种情况下,带有CellText的TextBlock将显示在Grid中。
以下示例显示了如何使用它:
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;
}
}