0

我有一组整数:

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>

我如何编写数据绑定来做到这一点?

4

1 回答 1

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>

我在里面使用 a BorderTextBlock但如果你愿意,你可以用别的东西代替它。重要的是Width绑定。

另请注意,Scores必须是一个属性。在上面的代码中,您正在创建一个公共字段,但绑定仅适用于属性,不适用于字段。

编辑:如果你想使用 a 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);
            }
        }
    }
}

用于此的 XAMLUserControl仅包含<Grid x:Name="grid" /><UserControl>元素内部。

somePrefix然后,假设您已绑定到命名空间,您可以按如下方式在 XAML 中使用它YourNamespace

    <somePrefix:BindableGrid Widths="{Binding Path=Scores}" />
于 2012-06-16T16:31:14.173 回答