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>

私はBordera をTextBlock内部に使用していますが、必要に応じて他のものに置き換えることができます。重要なのはWidthバインディングです。

Scoresプロパティでなければならないことにも注意してください。上記のコードでは、パブリック フィールドを作成していますが、バインドはプロパティでのみ機能し、フィールドでは機能しません。

EDIT : を使用する場合は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);
            }
        }
    }
}

このための XAML には、要素内UserControlのみが含まれます。<Grid x:Name="grid" /><UserControl>

somePrefix名前空間にバインドしていると仮定すると、次のように XAML で使用できますYourNamespace

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