C# Stackpanel datatrigger用于根据子项宽度设置方向
我知道我可以在这个场景中使用C# Stackpanel datatrigger用于根据子项宽度设置方向,c#,wpf,xaml,C#,Wpf,Xaml,我知道我可以在这个场景中使用WrapPanel,但是有什么方法可以实现我想要的。我想使用堆栈面板作为列表框的项目面板,其中方向设置为水平。在这种情况下,StackPanel的子控件可以延伸超过父控件/容器的宽度。例如,如果我有一个StackPanel,将5个文本块设置为水平方向,然后我拿着窗口,拖动宽度,使其在某个点变小,第5个文本框将从屏幕上延伸(隐藏)。在这一点上,我想要一些数据触发器,将方向设置为垂直,几乎像一个响应设计。有办法做到这一点吗 有办法做到这一点吗 您可以处理SizeChang
WrapPanel
,但是有什么方法可以实现我想要的。我想使用堆栈面板
作为列表框
的项目面板,其中方向设置为水平。在这种情况下,StackPanel
的子控件可以延伸超过父控件/容器的宽度。例如,如果我有一个StackPanel
,将5个文本块设置为水平方向,然后我拿着窗口,拖动宽度,使其在某个点变小,第5个文本框将从屏幕上延伸(隐藏)。在这一点上,我想要一些数据触发器,将方向设置为垂直,几乎像一个响应设计。有办法做到这一点吗
有办法做到这一点吗
您可以处理SizeChanged
事件。下面的代码示例应该会告诉您这个想法。如果最后一个元素(TextBox
)被隐藏,它会将方向设置为水平方向
,并在宽度增加时返回到垂直方向
private void ListBox_SizeChanged(object sender, SizeChangedEventArgs e)
{
ListBox lb = sender as ListBox;
ItemsPresenter ip = FindVisualChild<ItemsPresenter>(lb);
StackPanel sp = FindVisualChild<StackPanel>(ip);
UIElement lastElement = sp.Children[sp.Children.Count - 1];
bool isLastElementVisible = IsElementVisible(lastElement);
if (e.NewSize.Width < e.PreviousSize.Width && !isLastElementVisible)
sp.Orientation = Orientation.Vertical;
else if (e.NewSize.Width > e.PreviousSize.Width && isLastElementVisible)
sp.Orientation = Orientation.Horizontal;
}
private static T FindVisualChild<T>(DependencyObject parent, string childName = null) where T : DependencyObject
{
int count = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < count; i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
var childElement = child as FrameworkElement;
if (child is T && (childName == null || (childElement != null && childElement.Name == childName)))
{
return child as T;
}
else
{
var grandchild = FindVisualChild<T>(child, childName);
if (grandchild is T)
{
return grandchild;
}
}
}
return null;
}
private static bool IsElementVisible(UIElement element)
{
if (!element.IsVisible)
return false;
var container = VisualTreeHelper.GetParent(element) as FrameworkElement;
if (container == null) throw new ArgumentNullException("container");
Rect bounds = element.TransformToAncestor(container).TransformBounds(new Rect(0.0, 0.0, element.RenderSize.Width, element.RenderSize.Height));
Rect rect = new Rect(0.0, 0.0, container.ActualWidth, container.ActualHeight);
return rect.IntersectsWith(bounds);
}
private void ListBox\u SizeChanged(对象发送方,sizechangedventargs e)
{
ListBox lb=发送方作为ListBox;
ItemsPresenter ip=FindVisualChild(磅);
StackPanel sp=FindVisualChild(ip);
UIElement lastElement=sp.Children[sp.Children.Count-1];
bool isLastElementVisible=IsElementVisible(lastElement);
if(e.NewSize.Widthe.PreviousSize.Width&&isLastElementVisible)
sp.方向=水平方向;
}
私有静态T FindVisualChild(DependencyObject父对象,字符串childName=null),其中T:DependencyObject
{
int count=VisualTreeHelper.GetChildrenCount(父级);
for(int i=0;i
XAML:
<ListBox SizeChanged="ListBox_SizeChanged">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<TextBox Width="100" Text="1" />
<TextBox Width="100" Text="2" />
<TextBox Width="100" Text="3" />
<TextBox Width="100" Text="4" />
<TextBox Width="100" Text="5" />
</ListBox>
可以先尝试WrapPanel
而不是StackPanel?