ItemsControl,ListView,ListBox或DataGrid中可调整大小的行

时间:2014-10-22 04:04:08

标签: c# wpf

是否有可能在ItemsControlListViewListBoxDataGrid上调整行的大小?

我能做出我想要的唯一方法就是这样:

<UniformGrid Columns="1">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <SomeControlGoesHere />
        <GridSplitter Height="5" Background="Transparent" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Grid.Row="1" />
    </Grid>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <SomeControlGoesHere />
        <GridSplitter Height="5" Background="Transparent" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Grid.Row="1" />
    </Grid>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <SomeControlGoesHere />
        <GridSplitter Height="5" Background="Transparent" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Grid.Row="1" />
    </Grid>
</UniformGrid>

这是一个我可以调整大小的3个部分的示例。我想使数字任意,并绑定数据,并能够指定模板。

我无法使用任何ItemsControl重新创建此项,因为项容器必须是ContentControl,而哪个网格不是。如果网格被包裹在任何东西中,它的行为就像我需要的那样。

是否有使用这些控件进行构建的方法来执行此操作?

还有另一种方法可以创建像这样的可调整大小的部分吗?

更糟糕的是,是否有第三方控件可以做到这一点?

1 个答案:

答案 0 :(得分:0)

所以,我发现最好的方法是为此创建正确的网格。

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <SomeControl />
    <GridSplitter Height="5" VerticalAlignment="Center" HorizontalAlignment="Stretch" Grid.Row="1" />
    <SomeControl Grid.Row="2" />
</Grid>

所以我创建了一个继承Grid的自定义控件,允许我将项绑定到它。这不是功能齐全,几乎只有我需要的东西;一个是ItemTemplate

public class BindableGrid : Grid
{
    public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register( "ItemsSource", typeof( IEnumerable ), typeof( BindableGrid ), new FrameworkPropertyMetadata( null, OnItemsSourceChanged ) );

    public static readonly DependencyProperty ItemTemplateProperty = DependencyProperty.Register( "ItemTemplate", typeof( DataTemplate ), typeof( BindableGrid ), new FrameworkPropertyMetadata( null, OnItemTemplateChanged ) );

    public IEnumerable ItemsSource
    {
        get { return (IEnumerable)GetValue( ItemsSourceProperty ); }
        set { SetValue( ItemsSourceProperty, value ); }
    }

    public DataTemplate ItemTemplate
    {
        get { return (DataTemplate)GetValue( ItemTemplateProperty ); }
        set { SetValue( ItemTemplateProperty, value ); }
    }

    public static void OnItemsSourceChanged( DependencyObject d, DependencyPropertyChangedEventArgs e )
    {
        ( (BindableGrid)d ).OnItemsSourceChanged( (IEnumerable)e.OldValue, (IEnumerable)e.NewValue );
    }

    public void OnItemsSourceChanged( IEnumerable oldValue, IEnumerable newValue )
    {
        INotifyCollectionChanged oldValueNotify;
        if( ( oldValueNotify = oldValue as INotifyCollectionChanged ) != null )
        {
            oldValueNotify.CollectionChanged -= ItemsSourceCollectionChanged;
        }

        INotifyCollectionChanged newValueNotify;
        if( ( newValueNotify = newValue as INotifyCollectionChanged ) != null )
        {
            newValueNotify.CollectionChanged += ItemsSourceCollectionChanged;
        }
    }

    public static void OnItemTemplateChanged( DependencyObject d, DependencyPropertyChangedEventArgs e )
    {
        ( (BindableGrid)d ).OnItemTemplateChanged( (DataTemplate)e.OldValue, (DataTemplate)e.NewValue );
    }

    public void OnItemTemplateChanged( DataTemplate oldItemTemplate, DataTemplate newItemTemplate )
    {
    }

    private void ItemsSourceCollectionChanged( object sender, NotifyCollectionChangedEventArgs e )
    {
        if( e.Action == NotifyCollectionChangedAction.Reset )
        {
            RowDefinitions.Clear();
            Children.Clear();
        }
        else if( e.Action == NotifyCollectionChangedAction.Add )
        {
            AddItems( e.NewItems );
        }
        else
        {
            throw new InvalidOperationException( string.Format( "Action '{0}' is not valid.", e.Action ) );
        }
    }

    private void AddItems( IList items )
    {
        foreach( var item in items )
        {
            if( Children.Count > 0 )
            {
                RowDefinitions.Add( new RowDefinition { Height = GridLength.Auto } );
                var gridSplitter = new GridSplitter
                {
                    Height = 5,
                    Background = new SolidColorBrush( Color.FromArgb( 255, 0, 0, 0 ) ),
                    VerticalAlignment = VerticalAlignment.Center,
                    HorizontalAlignment = HorizontalAlignment.Stretch,
                };
                SetRow( gridSplitter, Children.Count );
                Children.Add( gridSplitter );
            }

            RowDefinitions.Add( new RowDefinition
            {
                Height = new GridLength( 1, GridUnitType.Star ),
                MinHeight = 40,
            } );
            var contentPresenter = new ContentPresenter();
            contentPresenter.SetValue( ContentPresenter.ContentTemplateProperty, ItemTemplate );
            contentPresenter.Content = item;
            SetRow( contentPresenter, Children.Count );
            Children.Add( contentPresenter );
        }
    }
}