Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.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 网格中的扩展器_Wpf_Layout - Fatal编程技术网

Wpf 网格中的扩展器

Wpf 网格中的扩展器,wpf,layout,Wpf,Layout,毫无疑问,这将是直截了当的,但不管出于什么原因,我的脑子里一片空白 我有一个小的,不可调整大小的窗口(325x450),其中有3个扩展器,垂直堆叠。每个扩展程序都包含一个ItemsControl,该控件中可能有很多项,因此需要滚动 我似乎没有弄清楚的是如何布局扩展器,以便它们可以扩展到任何可用的空间,而无需将其他元素从屏幕上推出。我可以通过使用网格并将每个扩展器以*高度排成一行来实现我所追求的目标,但这意味着它们总是占据窗口的1/3,这会破坏扩展器的点:) 我想要达到的目标的糟糕图表: 如果您不

毫无疑问,这将是直截了当的,但不管出于什么原因,我的脑子里一片空白

我有一个小的,不可调整大小的窗口(325x450),其中有3个扩展器,垂直堆叠。每个扩展程序都包含一个ItemsControl,该控件中可能有很多项,因此需要滚动

我似乎没有弄清楚的是如何布局扩展器,以便它们可以扩展到任何可用的空间,而无需将其他元素从屏幕上推出。我可以通过使用网格并将每个扩展器以*高度排成一行来实现我所追求的目标,但这意味着它们总是占据窗口的1/3,这会破坏扩展器的点:)

我想要达到的目标的糟糕图表:


如果您不介意后面有一点代码,您可能会挂接到
展开的
/
折叠的
事件中,找到父
网格
,获取扩展器的
行定义
,并将值设置为
*
如果展开,或
自动

比如说,

Expander ex = sender as Expander;
Grid parent = FindAncestor<Grid>(ex);
int rowIndex = Grid.GetRow(ex);

if (parent.RowDefinitions.Count > rowIndex && rowIndex >= 0)
    parent.RowDefinitions[rowIndex].Height = 
        (ex.IsExpanded ? new GridLength(1, GridUnitType.Star) : GridLength.Auto);

此要求有点不寻常,因为您希望
网格中
子项的状态决定
行定义的
高度

不过,我真的很喜欢这个布局想法,我不敢相信我自己从来没有过类似的要求:)

对于可重用的解决方案,我将为
网格
使用附加的行为
该行为将订阅附加的事件
Expander.Expanded
Expander.Collapsed
,并在事件处理程序中,从
Grid.GetRow
获取正确的
行定义
,并相应地更新
高度。它是这样工作的

<Grid ex:GridExpanderSizeBehavior.SizeRowsToExpanderState="True">
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Expander Grid.Row="0" ... />
    <Expander Grid.Row="1" ... />
    <Expander Grid.Row="2" ... />
    <!-- ... -->
</Grid>

这里是GridExpanderSizeBehavior

public class GridExpanderSizeBehavior
{
    public static DependencyProperty SizeRowsToExpanderStateProperty =
        DependencyProperty.RegisterAttached("SizeRowsToExpanderState",
                                            typeof(bool),
                                            typeof(GridExpanderSizeBehavior),
                                            new FrameworkPropertyMetadata(false, SizeRowsToExpanderStateChanged));
    public static void SetSizeRowsToExpanderState(Grid grid, bool value)
    {
        grid.SetValue(SizeRowsToExpanderStateProperty, value);
    }
    private static void SizeRowsToExpanderStateChanged(object target, DependencyPropertyChangedEventArgs e)
    {
        Grid grid = target as Grid;
        if (grid != null)
        {
            if ((bool)e.NewValue == true)
            {
                grid.AddHandler(Expander.ExpandedEvent, new RoutedEventHandler(Expander_Expanded));
                grid.AddHandler(Expander.CollapsedEvent, new RoutedEventHandler(Expander_Collapsed));
            }
            else if ((bool)e.OldValue == true)
            {
                grid.RemoveHandler(Expander.ExpandedEvent, new RoutedEventHandler(Expander_Expanded));
                grid.RemoveHandler(Expander.CollapsedEvent, new RoutedEventHandler(Expander_Collapsed));
            }
        }
    }
    private static void Expander_Expanded(object sender, RoutedEventArgs e)
    {
        Grid grid = sender as Grid;
        Expander expander = e.OriginalSource as Expander;
        int row = Grid.GetRow(expander);
        if (row <= grid.RowDefinitions.Count)
        {
            grid.RowDefinitions[row].Height = new GridLength(1.0, GridUnitType.Star); 
        }
    }
    private static void Expander_Collapsed(object sender, RoutedEventArgs e)
    {
        Grid grid = sender as Grid;
        Expander expander = e.OriginalSource as Expander;
        int row = Grid.GetRow(expander);
        if (row <= grid.RowDefinitions.Count)
        {
            grid.RowDefinitions[row].Height = new GridLength(1.0, GridUnitType.Auto);
        }
    }
}
公共类GridExpanderSizeBehavior
{
公共静态从属属性SizeRowsToExpanderStateProperty=
DependencyProperty.RegisterAttached(“SizeRowsToExpanderState”,
类型(bool),
类型(GridExpanderSizeBehavior),
新的FrameworkPropertyMetadata(false,SizeRowsToExpanderStateChanged);
公共静态void SetSizeRowsToExpanderState(网格,布尔值)
{
SetValue(SizeRowsToExpanderStateProperty,value);
}
私有静态void SizeRowsToExpanderStateChanged(对象目标,DependencyPropertyChangedEventArgs e)
{
网格=目标作为网格;
如果(网格!=null)
{
if((bool)e.NewValue==true)
{
AddHandler(Expander.ExpandedEvent,新RoutedEventHandler(Expander_Expanded));
AddHandler(Expander.CollapsedEvent,新RoutedEventHandler(Expander_Collapsed));
}
如果((bool)e.OldValue==true),则为else
{
grid.RemoveHandler(Expander.ExpandedEvent,新路由EventHandler(Expander_Expanded));
grid.RemoveHandler(Expander.CollapsedEvent,新路由EventHandler(Expander_collapse));
}
}
}
专用静态无效扩展器\u已扩展(对象发送器,路由目标)
{
网格网格=发送方作为网格;
扩展器扩展器=e.作为扩展器的原始源;
int row=Grid.GetRow(扩展器);

如果(行不确定这是否可行,但您可以尝试为每个网格行定义设置MaxHeight,然后在该行中的扩展器展开时清除MaxHeight。不幸的是,MaxHeight不是依赖属性,因此这可能需要一些代码隐藏或附加行为。是的,这样就可以了!事件已展开/Collapsed btw:)谢谢!@Tom我刚查过,但你比我快:)@Tom lol,谢谢你的编辑,我从来没有注意到我的WPF库一直都有祖先的拼写错误。没问题。如果编译器没有标记它,我可能不会注意到!我的代码无疑充满了拼写错误或是英国/美国拼写的混乱:)
public class GridExpanderSizeBehavior
{
    public static DependencyProperty SizeRowsToExpanderStateProperty =
        DependencyProperty.RegisterAttached("SizeRowsToExpanderState",
                                            typeof(bool),
                                            typeof(GridExpanderSizeBehavior),
                                            new FrameworkPropertyMetadata(false, SizeRowsToExpanderStateChanged));
    public static void SetSizeRowsToExpanderState(Grid grid, bool value)
    {
        grid.SetValue(SizeRowsToExpanderStateProperty, value);
    }
    private static void SizeRowsToExpanderStateChanged(object target, DependencyPropertyChangedEventArgs e)
    {
        Grid grid = target as Grid;
        if (grid != null)
        {
            if ((bool)e.NewValue == true)
            {
                grid.AddHandler(Expander.ExpandedEvent, new RoutedEventHandler(Expander_Expanded));
                grid.AddHandler(Expander.CollapsedEvent, new RoutedEventHandler(Expander_Collapsed));
            }
            else if ((bool)e.OldValue == true)
            {
                grid.RemoveHandler(Expander.ExpandedEvent, new RoutedEventHandler(Expander_Expanded));
                grid.RemoveHandler(Expander.CollapsedEvent, new RoutedEventHandler(Expander_Collapsed));
            }
        }
    }
    private static void Expander_Expanded(object sender, RoutedEventArgs e)
    {
        Grid grid = sender as Grid;
        Expander expander = e.OriginalSource as Expander;
        int row = Grid.GetRow(expander);
        if (row <= grid.RowDefinitions.Count)
        {
            grid.RowDefinitions[row].Height = new GridLength(1.0, GridUnitType.Star); 
        }
    }
    private static void Expander_Collapsed(object sender, RoutedEventArgs e)
    {
        Grid grid = sender as Grid;
        Expander expander = e.OriginalSource as Expander;
        int row = Grid.GetRow(expander);
        if (row <= grid.RowDefinitions.Count)
        {
            grid.RowDefinitions[row].Height = new GridLength(1.0, GridUnitType.Auto);
        }
    }
}