我有一组整数:
public ObservableCollection<int> Scores = new ObservableCollection<int> {
10, 30, 50
};
我希望在绑定时产生类似于以下XAML的内容:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0">10</TextBlock>
<TextBlock Grid.Column="1">30</TextBlock>
<TextBlock Grid.Column="2">50</TextBlock>
</Grid>
如何编写数据绑定来执行此操作?
答案 0 :(得分:0)
您可以尝试以下内容:
<ItemsControl ItemsSource="{Binding Path=Scores}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="1"
Background="Yellow" Width="{Binding}">
<TextBlock Text="{Binding}" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
我正在使用Border
,其中包含TextBlock
,但如果您愿意,可以将其替换为其他内容。重要的是Width
绑定。
另请注意,Scores
必须是属性。在上面的代码中,您创建了一个公共字段,但绑定仅适用于属性,而不适用于字段。
编辑:如果您想使用Grid
,可以尝试使用以下用户控件。此用户控件具有网格宽度的依赖项属性,并在每次集合更改时重新创建网格。
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Controls;
namespace YourNamespace
{
public partial class BindableGrid : UserControl
{
public static readonly DependencyProperty WidthsProperty =
DependencyProperty.Register("Widths",
typeof(ObservableCollection<int>),
typeof(BindableGrid),
new PropertyMetadata(Widths_Changed));
public BindableGrid()
{
InitializeComponent();
}
public ObservableCollection<int> Widths
{
get { return (ObservableCollection<int>)GetValue(WidthsProperty); }
set { SetValue(WidthsProperty, value); }
}
private static void Widths_Changed(DependencyObject obj,
DependencyPropertyChangedEventArgs e)
{
var grid = obj as BindableGrid;
if (grid != null)
{
grid.OnWidthsChanged(e.OldValue as ObservableCollection<int>);
}
}
private void OnWidthsChanged(ObservableCollection<int> oldValue)
{
if (oldValue != null)
{
oldValue.CollectionChanged -= Widths_CollectionChanged;
}
if (Widths != null)
{
Widths.CollectionChanged += Widths_CollectionChanged;
}
RecreateGrid();
}
private void Widths_CollectionChanged(object sender,
NotifyCollectionChangedEventArgs e)
{
// We'll just clear and recreate the entire grid each time
// the collection changes.
// Alternatively, you could use e.Action to determine what the
// actual change was and apply that (e.g. add or delete a
// single column definition).
RecreateGrid();
}
private void RecreateGrid()
{
// Recreate the column definitions.
grid.ColumnDefinitions.Clear();
foreach (int width in Widths)
{
// Use new GridLength(1, GridUnitType.Star) for a "*" column.
var coldef = new ColumnDefinition() { Width = new GridLength(width) };
grid.ColumnDefinitions.Add(coldef);
}
// Now recreate the content of the grid.
grid.Children.Clear();
for (int i = 0; i < Widths.Count; ++i)
{
int width = Widths[i];
var textblock = new TextBlock() { Text = width.ToString() };
Grid.SetColumn(textblock, i);
grid.Children.Add(textblock);
}
}
}
}
此UserControl
的XAML仅在<Grid x:Name="grid" />
元素中包含<UserControl>
。
然后,您可以在XAML中使用它,假设您已将somePrefix
绑定到命名空间YourNamespace
:
<somePrefix:BindableGrid Widths="{Binding Path=Scores}" />