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