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
C# Stackpanel datatrigger用于根据子项宽度设置方向_C#_Wpf_Xaml - Fatal编程技术网

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?