如何UpdatePaay的StackPanel?

时间:2011-09-02 21:59:47

标签: c# wpf xaml

问题是,如果您点击按钮并展开电话号码,则会出现堆叠面板和电话号码。边界扩展,这是伟大的,但如果你崩溃它,stackpanel&边界不要崩溃。

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        Background="White"
        >
    <StackPanel>
        <Border BorderBrush="Black" BorderThickness="1">
            <ListBox x:Name="myListBox">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Background="LightBlue" >
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="John Smith"/>
                                <Button Click="Button_Click" Width="25" Height="25"/>
                            </StackPanel>
                            <StackPanel x:Name="PhoneNumber" Visibility="Collapsed">
                                <TextBlock Text="12345"/>
                            </StackPanel>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </Border>
    </StackPanel>
</Window>

使用以下代码隐藏:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            myListBox.ItemsSource = new List<int>() { 1, 2 }; //add 2 elements; 
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Button btn = sender as Button;

            StackPanel sp1 = VisualTreeHelper.GetParent(btn) as StackPanel;
            StackPanel sp2 = VisualTreeHelper.GetParent(sp1) as StackPanel;

            StackPanel phone = sp2.FindName("PhoneNumber") as StackPanel;

            if (phone.Visibility == System.Windows.Visibility.Collapsed)
                phone.Visibility = System.Windows.Visibility.Visible; 
            else
                phone.Visibility = System.Windows.Visibility.Collapsed;

            myListBox.UpdateLayout(); //these don't collapse my space
            this.UpdateLayout(); //these don't collapse my space
        }
    }
}

2 个答案:

答案 0 :(得分:3)

没有深入研究这一点,但看起来您必须将InvalidateMeasure一直调到链ItemsPresenter(实际上是ItemsPanelTemplate)。如果我能用更好的东西,我会更新

private void Button_Click(object sender, RoutedEventArgs e)
{
    Button btn = sender as Button;

    StackPanel sp1 = VisualTreeHelper.GetParent(btn) as StackPanel;
    StackPanel sp2 = VisualTreeHelper.GetParent(sp1) as StackPanel;

    StackPanel phone = sp2.FindName("PhoneNumber") as StackPanel;

    if (phone.Visibility == System.Windows.Visibility.Collapsed)
        phone.Visibility = System.Windows.Visibility.Visible; 
    else
        phone.Visibility = System.Windows.Visibility.Collapsed;

    DependencyObject dpObject = btn;
    while (dpObject != null)
    {
        if (dpObject is UIElement)
        {
            (dpObject as UIElement).InvalidateMeasure();
        }
        if (dpObject is ItemsPresenter)
            break;
        dpObject = VisualTreeHelper.GetParent(dpObject);
    }
}

答案 1 :(得分:1)

问题是Listbox正在使用虚拟化。如果你禁用它,那么问题就会消失,如下所示:

<ListBox x:Name="myListBox" BorderBrush="Black" BorderThickness="1">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
</ListBox>

或者,您可以保留默认的ItemsPanel并在ListBox上设置ScrollViewer.CanContentScroll="False"。两者都禁用虚拟化。

我相信this question是相关的。