Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/magento/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf ItemsControl-栅格子元素自动调整大小_Wpf_Xaml_Blend - Fatal编程技术网

Wpf ItemsControl-栅格子元素自动调整大小

Wpf ItemsControl-栅格子元素自动调整大小,wpf,xaml,blend,Wpf,Xaml,Blend,我用Rachel Lim来获取动态行数。我想要实现的是让每一行显示在另一行的下方(完成),能够调整它们的大小(完成-使用GridSplitter),并使内容的大小与屏幕大小成比例 结果: 我想要的是: Xaml: <Grid> <ItemsControl ItemsSource="{Binding RowSource}" > <ItemsControl.ItemsPanel> <ItemsPanelTe

我用Rachel Lim来获取动态行数。我想要实现的是让每一行显示在另一行的下方(完成),能够调整它们的大小(完成-使用GridSplitter),并使内容的大小与屏幕大小成比例

结果:

我想要的是:

Xaml:

<Grid>
    <ItemsControl ItemsSource="{Binding RowSource}" >
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Grid local:GridHelper.RowCount="{Binding RowCount}" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemContainerStyle>
            <Style TargetType="ContentPresenter">
                <Setter Property="Grid.Row" Value="{Binding RowNumber}"/>
            </Style>
        </ItemsControl.ItemContainerStyle>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <DataGrid>
                            <DataGrid.Columns>
                                <DataGridTextColumn Header="Col 1" />
                                <DataGridTextColumn Header="Col 2" />
                                <DataGridTextColumn Header="Col 3" />
                            </DataGrid.Columns>
                        </DataGrid>
                        <Button Grid.Column="1" Content="Btn" />
                    </Grid>
                    <GridSplitter Height="5" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Grid.Row="0" ResizeDirection="Rows" ResizeBehavior="CurrentAndNext"/>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>
internal class MyViewModel
{
    public ObservableCollection<RowInfo> RowSource { get; set; }

    public int RowCount { get { return RowSource.Count; } }

    public MyViewModel()
    {
        RowSource = new ObservableCollection<RowInfo>()
        {
            new RowInfo() { RowNumber = 0 },
            new RowInfo() { RowNumber = 1 },
            new RowInfo() { RowNumber = 2 }
        };
    }
}
public class RowInfo
{
    public int RowNumber { get; internal set; }
}

对您在
GridHelper
类中创建的
RowDefinitions
使用星形大小调整:

public static void RowCountChanged(
    DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
    if (!(obj is Grid) || (int)e.NewValue < 0)
        return;

    Grid grid = (Grid)obj;
    grid.RowDefinitions.Clear();

    for (int i = 0; i < (int)e.NewValue; i++)
        grid.RowDefinitions.Add(
            new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) }); //<--

    SetStarRows(grid);
}

我认为你的方法是完全错误的。您不能使用
ItemsControl
,因为
GridSplitter
项需要位于
ItemsPanel
级别,而不是
DataTemplate
-否则,它将无法工作

最好在网格本身上使用自定义行为-请参见下面的示例代码:

    public class GridAutoRowChildBehavior : Behavior<Grid>
{
    public static readonly DependencyProperty ItemTemplateProperty =
        DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(GridAutoRowChildBehavior),
            new PropertyMetadata(null, OnGridPropertyChanged));

    public static readonly DependencyProperty ItemsSourceProperty =
        DependencyProperty.Register("ItemsSource", typeof(object), typeof(GridAutoRowChildBehavior),
            new PropertyMetadata(null, OnGridPropertyChanged));

    private static void OnGridPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ((GridAutoRowChildBehavior) d).ResetGrid();
    }

    private void ResetGrid()
    {
        var source = ItemsSource as IEnumerable;
        if (source == null || ItemTemplate == null)
            return;
        AssociatedObject.Children.Clear();
        AssociatedObject.RowDefinitions.Clear();
        var count = 0;
        foreach (var item in source)
        {
            var content = new ContentPresenter
            {
                ContentTemplate = ItemTemplate,
                Content = item
            };
            var splitter = new GridSplitter
            {
                Height = 5,
                VerticalAlignment = VerticalAlignment.Bottom,
                HorizontalAlignment = HorizontalAlignment.Stretch
            };
            AssociatedObject.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
            Grid.SetRow(content,count);
            Grid.SetRow(splitter,count);
            AssociatedObject.Children.Add(content);
            AssociatedObject.Children.Add(splitter);
            count++;
        }

    }

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


    public object ItemsSource
    {
        get { return GetValue(ItemsSourceProperty); }
        set { SetValue(ItemsSourceProperty, value); }
    }
}
公共类GridAutoRowChildBehavior:Behavior
{
公共静态只读DependencyProperty ItemTemplateProperty=
DependencyProperty.Register(“ItemTemplate”、typeof(DataTemplate)、typeof(GridAutoRowChildBehavior),
新的PropertyMetadata(null,OnGridPropertyChanged));
公共静态只读依赖项Property ItemsSourceProperty=
DependencyProperty.Register(“ItemsSource”、typeof(object)、typeof(GridAutoRowChildBehavior),
新的PropertyMetadata(null,OnGridPropertyChanged));
私有静态void OnGridPropertyChanged(DependencyObject d、DependencyPropertyChangedEventArgs e)
{
((GridAutoRowChildBehavior)d).ResetGrid();
}
私有void ResetGrid()
{
var source=ItemsSource作为IEnumerable;
if(source==null | | ItemTemplate==null)
返回;
AssociatedObject.Children.Clear();
AssociatedObject.RowDefinitions.Clear();
var计数=0;
foreach(源中的var项)
{
var content=newcontentpresenter
{
ContentTemplate=ItemTemplate,
内容=项目
};
var splitter=新的GridSplitter
{
高度=5,
垂直对齐=垂直对齐。底部,
水平对齐=水平对齐。拉伸
};
AssociatedObject.RowDefinitions.Add(新行定义{Height=new GridLength(1,GridUnitType.Star)});
Grid.SetRow(内容、计数);
Grid.SetRow(拆分器,计数);
AssociatedObject.Children.Add(内容);
AssociatedObject.Children.Add(拆分器);
计数++;
}
}
公共数据模板ItemTemplate
{
获取{return(DataTemplate)GetValue(ItemTemplateProperty);}
set{SetValue(ItemTemplateProperty,value);}
}
公共对象项资源
{
获取{返回GetValue(ItemsSourceProperty);}
set{SetValue(ItemsSourceProperty,value);}
}
}
然后在XAML中编写如下代码:

<Grid>
    <i:Interaction.Behaviors>
        <local:GridAutoRowChildBehavior ItemsSource="{Binding RowsSource}">
            <local:GridAutoRowChildBehavior.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <DataGrid>
                            <DataGrid.Columns>
                                <DataGridTextColumn Header="Col 1" />
                                <DataGridTextColumn Header="Col 2" />
                                <DataGridTextColumn Header="Col 3" />
                            </DataGrid.Columns>
                        </DataGrid>
                        <Button Grid.Column="1" Content="Btn" />
                    </Grid>
                </DataTemplate>
            </local:GridAutoRowChildBehavior.ItemTemplate>
        </local:GridAutoRowChildBehavior>
    </i:Interaction.Behaviors>
</Grid>

我已经测试了这个,它的工作原理完全符合你的需要


您还需要做的唯一一件事是将Nuget软件包添加到您的项目中,该软件包可以使内容按比例调整大小,但调整大小不正确。调整大小是什么意思?我想使用GridSplitter调整行的大小。我希望内容分布在整个视图中,当我调整窗口大小时,您也希望缩放行和列。我还想使用GridSplitter分别调整每一行的大小。我不确定我是否能很好地回答这个问题,你想要的是,默认情况下,即使行中没有内容,它们也应该有一定的高度。这就是需要的吗?是的,我希望行的大小与窗口大小成比例@mm8做对了这一部分,但是调整大小(使用GridSplitter)停止了,以便正常工作。哦,基本上,您希望内容分布在整个视图中,当我调整窗口大小时,您也希望缩放行和列?完全正确。但我还想使用GridSplitter分别调整每一行的大小。我会试着写一个控件。做得好,迪安!我在哪里可以深入阅读更多关于互动库的内容?这是一个很好的起点,对于可能阅读此内容的人来说只是一个小小的更新:如果您在ItemControl中有行为(与我一样,但在本示例中未显示),则必须覆盖OnAttached并在其中调用ResetGrid。受保护的重写void OnAttached(){base.OnAttached();ResetGrid();}还检查ResetGrid方法中的AssociatedObject是否为null。
<Grid>
    <i:Interaction.Behaviors>
        <local:GridAutoRowChildBehavior ItemsSource="{Binding RowsSource}">
            <local:GridAutoRowChildBehavior.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <DataGrid>
                            <DataGrid.Columns>
                                <DataGridTextColumn Header="Col 1" />
                                <DataGridTextColumn Header="Col 2" />
                                <DataGridTextColumn Header="Col 3" />
                            </DataGrid.Columns>
                        </DataGrid>
                        <Button Grid.Column="1" Content="Btn" />
                    </Grid>
                </DataTemplate>
            </local:GridAutoRowChildBehavior.ItemTemplate>
        </local:GridAutoRowChildBehavior>
    </i:Interaction.Behaviors>
</Grid>