我在网格中有一些StackPanel
个。它们填充有标签(所有标签的高度和可显示空间)。可能的XAML是:
<Grid>
<StackPanel>
<Label Content="bla" Background="lime" />
<Label ...>
...
</StackPanel>
</Grid>
每次Grid
的大小发生变化时,我都需要更改StackPanel
的内部内容。我需要隐藏仅部分显示的溢出Label
。为此,我可以使用以下解决方案:with a Converter和make a new class that is inherited from StackPanel。
我想通过使用附加属性创建一种不同的方式。我有以下代码:
//DepProp OverflowVisibility (double), can save height value
public static void Initialized(DependencyObject pObject, DependencyPropertyChangedEventArgs e)
{
var panel = (pObject as Panel) //the StackPanel in this case
panel.SizeChanged += panel_updateInnerLayout;
}
static void panel_LayoutUpdated(object sender, EventArgs e)
{
var parent = sender as Panel;
if(parent != null)
foreach(FrameworkElement element in parent.Children)
{
var elementPos = element.TransformToAncestor(parent).Transform(new Point(0,0));
if(element.ActualHeight + elementPos.Y >
(double)parent.GetValue(OverflowVisibilityProperty))
element.Visibility = Visibility.Hidden;
else
element.Visibility = Visibility.Visible;
}
}
以及在XAML中使用的示例:
<Grid>
<ItemsControl>
<ItemsPanel>
<ItemsPanelTemplate>
<StackPanel own:OverflowVisibility.OverflowVisibility="{Binding Grid height}" />
</ItemsPanelTemplate>
</ItemsPanel>
</ItemsControl>
</Grid>
每次StackPanel
更改大小时,我都可以使用panel_updateInnerLayout
事件处理程序更新我的标签。当StackPanel
的大小发生变化时,一切正常。
我的问题:StackPanel
本身并不会引发SizeChanged
,因为它的高度高于Grid
。每当Grid
改变其高度时,我都需要一个提升的事件。
我的问题:是否有任何事件而非SizeChanged
,每次更改Grid
尺寸时都会调用此事件?如果没有,是否有另一种附加属性来解决我的问题呢?
我还尝试设置StackPanel
到ItemsControl
ActualHeight高度的绑定,但它不会提升SizeChanged
。
答案 0 :(得分:1)
不幸的是,您选择了错误的Panel
控件来满足您的要求。 StackPanel
只应在其内容的大小调整不时使用,因为它不提供任何子控件调整大小的能力。因此,您应该使用提供调整大小功能的Grid
或任何其他Panel
。有关选择相应Panel
的更多帮助,请参阅MSDN上的Panels Overview页面。
答案 1 :(得分:0)
有两种可能的事件:SizeChanged
和LayoutUpdated
。 SizeChanged
无法正常工作,因为StackPanel未调整大小。 LayoutUpdated
不起作用,因为此事件的sender
始终为null
,我无法找到StackPanel的来源。
有关详情,请参阅:Layout Events - SizeChanged and LayoutUpdated。
所以我的方法没有可能的事件。
当我搜索解决方案时,我也发现,我还使用附加属性一词来表示附加行为和混合行为 。区别在于here。摘要:属性对对象不执行任何操作,但可以使用它们的存在,行为会更改对象行为。混合行为是Microsoft为Microsoft Blend创建的行为。我的问题中的代码是附加行为。
对于附加行为我没有找到解决方案,但对于 Blend行为,我发现了一些。您需要添加引用Micosoft.Windows.Interactivity
。
之后我使用了这段代码:
public class OverflowVisibilityBehavior : Behavior<VirtualizingStackPanel>
{
protected override void OnAttached()
{
AssociatedObject.LayoutUpdated += AssociatedObject_LayoutUpdated;
base.OnAttached();
}
protected override void OnDetaching()
{
AssociatedObject.LayoutUpdated -= AssociatedObject_LayoutUpdated;
}
void AssociatedObject_LayoutUpdated(object sender, EventArgs e)
{
var parent = AssociatedObject; //that solves the problem: you can get a "sender" information
//...
// Instead of property GetValue
(VisualTreeHelper.GetParent(parent) as ItemsPresenter).ActualHeight
}
}
还剩下一些问题:StackPanel的父级必须引发SizeChanged
。如果您在StackPanel
中StackPanel
加Grid
,则需要对其进行修改。
第二:LayoutUpdated
多次更改StackPanel
。比我需要的次数多。